Make string literals work properly

This commit is contained in:
Greg Shuflin 2021-11-13 13:45:52 -08:00
parent a93fc48ee8
commit a00125d4a5
3 changed files with 30 additions and 3 deletions

View File

@ -197,6 +197,7 @@ pub struct TypeSingletonName {
pub enum ExpressionKind {
NatLiteral(u64),
FloatLiteral(f64),
//TODO StringLiteral variant needs to support prefixes
StringLiteral(Rc<String>),
BoolLiteral(bool),
BinExp(BinOp, Box<Expression>, Box<Expression>),

View File

@ -435,12 +435,19 @@ peg::parser! {
}
}
//TODO need to do something with prefix in the AST
rule string_literal() -> ExpressionKind =
s:bare_string_literal(){ ExpressionKind::StringLiteral(Rc::new(s.to_string())) }
prefix:identifier()? s:bare_string_literal(){ ExpressionKind::StringLiteral(Rc::new(s.to_string())) }
//TODO string escapes, prefixes
rule bare_string_literal() -> &'input str =
"\"" items:$([^ '"' ]*) "\"" { items }
"\"" s:$(string_component()*) "\"" { s }
rule string_component() -> &'input str =
r#"\\"# { "\\" } /
r#"\""# { "\"" } /
r#"\t"# { "\t" } /
r#"\n"# { "\n" } /
ch:$([^ '"' ]) { ch }
rule bool_literal() -> ExpressionKind =
"true" { ExpressionKind::BoolLiteral(true) } / "false" { ExpressionKind::BoolLiteral(false) }

View File

@ -135,7 +135,17 @@ fn basic_literals() {
assert_expr!("0xf_f_", expr(NatLiteral(255)));
assert_expr!("false", expr(BoolLiteral(false)));
assert_expr!("true", expr(BoolLiteral(true)));
}
#[test]
fn string_literals() {
use ExpressionKind::*;
assert_expr!(r#""""#, expr(StringLiteral(rc(""))));
assert_expr!(r#""hello""#, expr(StringLiteral(rc("hello"))));
assert_expr!(r#"b"some bytestring""#, expr(StringLiteral(rc("some bytestring"))));
//NOTE I'm not 100% sure this case is correct, but I'll deal with it later
assert_expr!(r#""Do \n \" escapes work\t""#, expr(StringLiteral(rc(r#"Do \n \" escapes work\t"#))));
}
#[test]
@ -1309,3 +1319,12 @@ fn comments() {
let source = "5//no man\n";
assert_ast!(source, vec![exst(NatLiteral(5))]);
}
//TODO support backtick operators like this
/*
#[test]
fn backtick_operators() {
let output = token_kinds("1 `plus` 2");
assert_eq!(output, vec![digit!("1"), op!("plus"), digit!("2")]);
}
*/