ltcc: parsing of double quoted strings
use double quotes in examples
This commit is contained in:
parent
f5984e0b08
commit
08f592ad60
6 changed files with 78 additions and 23 deletions
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 } => {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
6
main.lt
6
main.lt
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue