ltcc: parsing of double quoted strings

use double quotes in examples
This commit is contained in:
Michael Sippel 2024-09-29 22:20:10 +02:00
parent f5984e0b08
commit 08f592ad60
Signed by: senvas
GPG key ID: F96CF119C34B64A6
6 changed files with 78 additions and 23 deletions

View file

@ -41,10 +41,14 @@ pub type TypeTag = Result<laddertypes::TypeTerm, TypeError>;
#[derive(Clone, Debug)]
pub enum LTExpr {
Literal {
WordLiteral {
typ: Option<TypeTag>,
val: tisc::VM_Word,
},
StringLiteral {
region: InputRegionTag,
value: String,
},
Symbol {
region: InputRegionTag,
typ: Option<TypeTag>,
@ -82,7 +86,7 @@ impl LTExpr {
}
*/
pub fn lit_uint(val: u64) -> Self {
LTExpr::Literal {
LTExpr::WordLiteral {
typ: None, //typectx.write().unwrap().parse("_2^64~machine::UInt64~machine::Word").expect("parse typeterm"),
val: val as tisc::VM_Word,
}

View file

@ -6,7 +6,7 @@ pub enum LTIRToken {
Num(i64),
// SingleQuote(String),
// DoubleQuote(String),
DoubleQuote(String),
// TripleQuote(String),
Lambda,
MapsTo,
@ -25,6 +25,7 @@ pub enum LTIRToken {
pub enum LexError {
InvalidDigit,
InvalidChar,
UnexpectedEnd
}
#[derive(PartialEq, Eq, Clone, Debug)]
@ -35,6 +36,7 @@ pub enum LexerState {
Sym(String),
Num(i64),
Char(Option<char>),
DoubleQuote(String)
}
impl LexerState {
@ -46,6 +48,7 @@ impl LexerState {
LexerState::Sym(s) => Some(LTIRToken::Symbol(s)),
LexerState::Num(n) => Some(LTIRToken::Num(n)),
LexerState::Char(c) => Some(LTIRToken::Char(c?)),
LexerState::DoubleQuote(s) => Some(LTIRToken::DoubleQuote(s))
}
}
}
@ -196,6 +199,12 @@ where
}
}
}
'\"' => {
self.chars.next();
self.position += 1;
region.end += 1;
state = LexerState::DoubleQuote(String::new());
}
c => {
if c.is_whitespace() {
self.chars.next();
@ -242,6 +251,36 @@ where
}
}
LexerState::DoubleQuote(val) => {
match self.chars.next() {
Some('\"') => {
self.position += 1;
region.end +=1;
break;
}
Some('\\') => {
match self.chars.next() {
Some('0') => {
val.push('\0');
}
Some('n') => {
val.push('\n');
}
Some('\\') => {
val.push('\\');
}
_ => {}
}
}
Some(c) => {
val.push(c);
}
None => {
return Some((region, Err(LexError::UnexpectedEnd)))
}
}
}
LexerState::Char(val) => {
self.position += 2;
region.end += 2;
@ -325,7 +364,6 @@ where
return Some((region, Err(LexError::InvalidDigit)));
}
}
_ => {}
}
}
@ -363,3 +401,4 @@ mod tests {
}
}
}

View file

@ -345,6 +345,12 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
Ok(LTIRToken::StatementSep) => {
break;
}
Ok(LTIRToken::DoubleQuote(s)) => {
let region = region.clone();
let value = s.clone();
tokens.next();
children.push(LTExpr::StringLiteral{ region, value });
}
Ok(LTIRToken::Symbol(name)) => match name.as_str() {
"if" => {
tokens.next();
@ -404,6 +410,7 @@ where It: Iterator<Item = (InputRegionTag, Result<LTIRToken, LexError>)>
mod tests {
use crate::parser::LTExpr;
use std::sync::{Arc, RwLock};
#[test]
@ -421,6 +428,19 @@ mod tests {
);
}
#[test]
fn test_parse_double_quote() {
let mut lexer = crate::lexer::LTIRLexer::from("\"test\"".chars()).peekable();
let typectx = Arc::new(RwLock::new(laddertypes::dict::TypeDict::new()));
let expr = crate::parser::parse_expr( &typectx, &mut lexer );
assert_eq!(
expr,
Ok(LTExpr::DoubleQuote("testlo".into()))
);
}
#[test]
fn test_parse_typed_atomic_binding() {
let mut lexer = crate::lexer::LTIRLexer::from("x:T".chars()).peekable();

View file

@ -225,7 +225,13 @@ impl ProcedureCompiler {
);
}
},
LTExpr::Literal { typ, val } => {
LTExpr::StringLiteral { region, value } => {
self.asm = self.asm.lit(0);
for c in value.chars().rev() {
self.asm = self.asm.lit(c as i64);
}
}
LTExpr::WordLiteral { typ, val } => {
self.asm = self.asm.lit(*val);
}
LTExpr::Application { typ, head, body } => {

View file

@ -16,19 +16,3 @@ export {
let int-max = λ{ a:~machine.Int64; b:~machine.Int64; } ↦ if( int-gt a b ) { a; } else { b; };
};
/* syntax ambiguity */
let f'0 = λx:A -> B ↦ { ... };
/* could be interpreted as .. */
let f'1 = λ{x: A -> B} ↦ {};
/* ..or.. */
let f'2 = λx:A ↦ B:{};
do {
!a 10;
!b 20;
}

View file

@ -1,5 +1,6 @@
{
print-nullterm 'H''e''l''l''o'' ''W''o''r''l''d''!''\n''\0';
export {
let main = λ{} ↦ {
print-nullterm "Hello World!\n";
/* test ratio
*/
@ -32,5 +33,6 @@
'\n''\0';
uint-machine-to-posint 16 256;
};
}