Compare commits

..

No commits in common. "d2b5deb802a576e086f5a57da0782f7a89d0b689" and "a9afb6d24e4b24159c4f3232ba8afabdb99281e9" have entirely different histories.

7 changed files with 28 additions and 42 deletions

View File

@ -202,7 +202,8 @@ pub struct TypeSingletonName {
pub enum ExpressionKind { pub enum ExpressionKind {
NatLiteral(u64), NatLiteral(u64),
FloatLiteral(f64), FloatLiteral(f64),
StringLiteral { prefix: Option<Rc<String>>, s: Rc<String> }, //TODO StringLiteral variant needs to support prefixes
StringLiteral(Rc<String>),
BoolLiteral(bool), BoolLiteral(bool),
BinExp(BinOp, Box<Expression>, Box<Expression>), BinExp(BinOp, Box<Expression>, Box<Expression>),
PrefixExp(PrefixOp, Box<Expression>), PrefixExp(PrefixOp, Box<Expression>),

View File

@ -71,7 +71,7 @@ pub fn walk_expression<V: ASTVisitor>(v: &mut V, expr: &Expression) {
if let Recursion::Continue = v.expression(expr) { if let Recursion::Continue = v.expression(expr) {
match &expr.kind { match &expr.kind {
NatLiteral(_) | FloatLiteral(_) | StringLiteral { .. } | BoolLiteral(_) | Value(_) => (), NatLiteral(_) | FloatLiteral(_) | StringLiteral(_) | BoolLiteral(_) | Value(_) => (),
BinExp(_, lhs, rhs) => { BinExp(_, lhs, rhs) => {
walk_expression(v, lhs); walk_expression(v, lhs);
walk_expression(v, rhs); walk_expression(v, rhs);

View File

@ -47,7 +47,7 @@ fn render_expression(expr: &Expression, indent: usize, buf: &mut String) {
match &expr.kind { match &expr.kind {
NatLiteral(n) => buf.push_str(&format!("(NatLiteral {})", n)), NatLiteral(n) => buf.push_str(&format!("(NatLiteral {})", n)),
FloatLiteral(f) => buf.push_str(&format!("(FloatLiteral {})", f)), FloatLiteral(f) => buf.push_str(&format!("(FloatLiteral {})", f)),
StringLiteral { s, prefix } => buf.push_str(&format!("(StringLiteral prefix: {:?} {})", prefix, s)), StringLiteral(s) => buf.push_str(&format!("(StringLiteral {})", s)),
BoolLiteral(b) => buf.push_str(&format!("(BoolLiteral {})", b)), BoolLiteral(b) => buf.push_str(&format!("(BoolLiteral {})", b)),
BinExp(binop, lhs, rhs) => { BinExp(binop, lhs, rhs) => {
let new_indent = indent + LEVEL; let new_indent = indent + LEVEL;

View File

@ -830,14 +830,11 @@ fn list_expr(input: Span) -> ParseResult<ExpressionKind> {
})(input) })(input)
} }
//TODO need to do something with prefix in the AST
fn string_literal(input: Span) -> ParseResult<ExpressionKind> { fn string_literal(input: Span) -> ParseResult<ExpressionKind> {
context( tok(map(pair(opt(identifier), bare_string_literal), |(_maybe_prefix, s)| {
"string-literal", ExpressionKind::StringLiteral(Rc::new(s))
tok(map(pair(opt(identifier), bare_string_literal), |(prefix, s)| ExpressionKind::StringLiteral { }))(input)
s: Rc::new(s),
prefix: prefix.map(|s| rc_string(s.fragment())),
})),
)(input)
} }
fn bare_string_literal(input: Span) -> ParseResult<String> { fn bare_string_literal(input: Span) -> ParseResult<String> {
@ -845,14 +842,7 @@ fn bare_string_literal(input: Span) -> ParseResult<String> {
alt((value("\\", tag("\\")), value("\"", tag("\"")), value("\n", tag("n")), value("\t", tag("t")))); alt((value("\\", tag("\\")), value("\"", tag("\"")), value("\n", tag("n")), value("\t", tag("t"))));
alt(( alt((
map(tag(r#""""#), |_| String::new()), map(tag(r#""""#), |_| String::new()),
preceded( delimited(char('"'), escaped_transform(none_of(r#""\"#), '\\', string_escape_transforms), char('"')),
peek(char('"')),
cut(delimited(
char('"'),
escaped_transform(none_of(r#""\"#), '\\', string_escape_transforms),
char('"'),
)),
),
))(input) ))(input)
} }

View File

@ -446,10 +446,9 @@ peg::parser! {
} }
} }
//TODO need to do something with prefix in the AST
rule string_literal() -> ExpressionKind = rule string_literal() -> ExpressionKind =
prefix:identifier()? s:bare_string_literal(){ ExpressionKind::StringLiteral{ s: Rc::new(s.to_string()), prefix:identifier()? s:bare_string_literal(){ ExpressionKind::StringLiteral(Rc::new(s.to_string())) }
prefix: prefix.map(rc_string)
} }
rule bare_string_literal() -> &'input str = rule bare_string_literal() -> &'input str =
"\"" s:$(string_component()*) "\"" { s } "\"" s:$(string_component()*) "\"" { s }

View File

@ -17,10 +17,6 @@ fn bx<T>(item: T) -> Box<T> {
Box::new(item) Box::new(item)
} }
fn strlit(s: &str) -> ExpressionKind {
ExpressionKind::StringLiteral { s: Rc::new(s.to_string()), prefix: None }
}
fn stmt(kind: StatementKind) -> Statement { fn stmt(kind: StatementKind) -> Statement {
Statement { location: Location::default(), id: ItemId::default(), kind } Statement { location: Location::default(), id: ItemId::default(), kind }
} }
@ -183,12 +179,9 @@ fn basic_literals() {
fn string_literals() { fn string_literals() {
use ExpressionKind::*; use ExpressionKind::*;
assert_expr!(r#""""#, expr(strlit(""))); assert_expr!(r#""""#, expr(StringLiteral(rc(""))));
assert_expr!(r#""hello""#, expr(strlit("hello"))); assert_expr!(r#""hello""#, expr(StringLiteral(rc("hello"))));
assert_expr!( assert_expr!(r#"b"some bytestring""#, expr(StringLiteral(rc("some bytestring"))));
r#"b"some bytestring""#,
expr(StringLiteral { s: rc("some bytestring"), prefix: Some(rc("b")) })
);
//NOTE I'm not 100% sure this case is correct, but I'll deal with it later //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("Do \n \" escapes work\t")))); //assert_expr!(r#""Do \n \" escapes work\t""#, expr(StringLiteral(rc("Do \n \" escapes work\t"))));
} }
@ -303,12 +296,15 @@ fn tuples() {
use ExpressionKind::*; use ExpressionKind::*;
assert_expr!("()", expr(TupleLiteral(vec![]))); assert_expr!("()", expr(TupleLiteral(vec![])));
assert_expr!(r#"("hella", 34)"#, expr(TupleLiteral(vec![expr(strlit("hella")), expr(NatLiteral(34))]))); assert_expr!(
r#"("hella", 34)"#,
expr(TupleLiteral(vec![expr(StringLiteral(rc("hella"))), expr(NatLiteral(34))]))
);
assert_expr!( assert_expr!(
r#"(1+2, "slough")"#, r#"(1+2, "slough")"#,
expr(TupleLiteral(vec![ expr(TupleLiteral(vec![
binop("+", expr(NatLiteral(1)), expr(NatLiteral(2))), binop("+", expr(NatLiteral(1)), expr(NatLiteral(2))),
expr(strlit("slough")), expr(StringLiteral(rc("slough"))),
])) ]))
); );
} }
@ -477,7 +473,7 @@ fn lambda_expressions() {
name: rc("String"), name: rc("String"),
params: vec![] params: vec![]
})), })),
body: vec![stmt(StatementKind::Expression(expr(strlit("q")))),].into() body: vec![stmt(StatementKind::Expression(expr(StringLiteral(rc("q"))))),].into()
}) })
); );
} }
@ -556,8 +552,9 @@ fn complex_lambdas() {
#[test] #[test]
fn reserved_words() { fn reserved_words() {
//TODO assert a good error message for this let err = "0: at line 1, in Verify:\nmodule::item::call()\n^\n\n1: at line 1, in token:\nmodule::item::call()\n^\n\n2: at line 1, in identifier:\nmodule::item::call()\n^\n\n3: at line 1, in token:\nmodule::item::call()\n^\n\n4: at line 1, in primary-expr-no-struct:\nmodule::item::call()\n^\n\n5: at line 1, in primary-expr:\nmodule::item::call()\n^\n\n6: at line 1, in extended-expr:\nmodule::item::call()\n^\n\n7: at line 1, in prefix-expr:\nmodule::item::call()\n^\n\n8: at line 1, in expression-kind:\nmodule::item::call()\n^\n\n9: at line 1, in Parsing-statement:\nmodule::item::call()\n^\n\n10: at line 1, in AST:\nmodule::item::call()\n^\n\n";
assert_fail!("module::item::call()"); assert_fail!("module::item::call()", err);
assert_expr!("modulek::item", expr(ExpressionKind::Value(qn!(modulek, item)))); assert_expr!("modulek::item", expr(ExpressionKind::Value(qn!(modulek, item))));
} }
@ -1281,7 +1278,7 @@ if (45, "panda", false, 2.2) {
expr( expr(
IfExpression { IfExpression {
discriminator: Some(bx(expr(TupleLiteral(vec![ discriminator: Some(bx(expr(TupleLiteral(vec![
expr(NatLiteral(45)), expr(strlit("panda")), expr(BoolLiteral(false)), expr(FloatLiteral(2.2)) expr(NatLiteral(45)), expr(StringLiteral(rc("panda"))), expr(BoolLiteral(false)), expr(FloatLiteral(2.2))
])))), ])))),
body: bx(IfExpressionBody::CondList(vec![ body: bx(IfExpressionBody::CondList(vec![
ConditionArm { ConditionArm {
@ -1294,7 +1291,7 @@ if (45, "panda", false, 2.2) {
] ]
)), )),
guard: None, guard: None,
body: vec![stmt(StatementKind::Expression(expr(strlit("no"))))].into(), body: vec![stmt(StatementKind::Expression(expr(StringLiteral(rc("no")))))].into(),
}, },
ConditionArm { ConditionArm {
condition: Condition::Pattern(Pattern::TuplePattern( condition: Condition::Pattern(Pattern::TuplePattern(
@ -1306,12 +1303,12 @@ if (45, "panda", false, 2.2) {
] ]
)), )),
guard: None, guard: None,
body: vec![stmt(StatementKind::Expression(expr(strlit("yes"))))].into(), body: vec![stmt(StatementKind::Expression(expr(StringLiteral(rc("yes")))))].into(),
}, },
ConditionArm { ConditionArm {
condition: Condition::Pattern(Pattern::Ignored), condition: Condition::Pattern(Pattern::Ignored),
guard: None, guard: None,
body: vec![exst(strlit("maybe"))].into(), body: vec![exst(StringLiteral(rc("maybe")))].into(),
}, },
])) ]))
} }

View File

@ -126,8 +126,7 @@ impl<'a, 'b> Reducer<'a, 'b> {
match &expr.kind { match &expr.kind {
NatLiteral(n) => Expression::Literal(Literal::Nat(*n)), NatLiteral(n) => Expression::Literal(Literal::Nat(*n)),
FloatLiteral(f) => Expression::Literal(Literal::Float(*f)), FloatLiteral(f) => Expression::Literal(Literal::Float(*f)),
//TODO implement handling string literal prefixes StringLiteral(s) => Expression::Literal(Literal::StringLit(s.clone())),
StringLiteral { s, prefix: _ } => Expression::Literal(Literal::StringLit(s.clone())),
BoolLiteral(b) => Expression::Literal(Literal::Bool(*b)), BoolLiteral(b) => Expression::Literal(Literal::Bool(*b)),
BinExp(binop, lhs, rhs) => self.binop(binop, lhs, rhs), BinExp(binop, lhs, rhs) => self.binop(binop, lhs, rhs),
PrefixExp(op, arg) => self.prefix(op, arg), PrefixExp(op, arg) => self.prefix(op, arg),