Compare commits
2 Commits
a9afb6d24e
...
d2b5deb802
Author | SHA1 | Date | |
---|---|---|---|
|
d2b5deb802 | ||
|
2ba0fb4869 |
@ -202,8 +202,7 @@ pub struct TypeSingletonName {
|
|||||||
pub enum ExpressionKind {
|
pub enum ExpressionKind {
|
||||||
NatLiteral(u64),
|
NatLiteral(u64),
|
||||||
FloatLiteral(f64),
|
FloatLiteral(f64),
|
||||||
//TODO StringLiteral variant needs to support prefixes
|
StringLiteral { prefix: Option<Rc<String>>, s: Rc<String> },
|
||||||
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>),
|
||||||
|
@ -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);
|
||||||
|
@ -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) => buf.push_str(&format!("(StringLiteral {})", s)),
|
StringLiteral { s, prefix } => buf.push_str(&format!("(StringLiteral prefix: {:?} {})", prefix, 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;
|
||||||
|
@ -830,11 +830,14 @@ 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> {
|
||||||
tok(map(pair(opt(identifier), bare_string_literal), |(_maybe_prefix, s)| {
|
context(
|
||||||
ExpressionKind::StringLiteral(Rc::new(s))
|
"string-literal",
|
||||||
}))(input)
|
tok(map(pair(opt(identifier), bare_string_literal), |(prefix, s)| ExpressionKind::StringLiteral {
|
||||||
|
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> {
|
||||||
@ -842,7 +845,14 @@ 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()),
|
||||||
delimited(char('"'), escaped_transform(none_of(r#""\"#), '\\', string_escape_transforms), char('"')),
|
preceded(
|
||||||
|
peek(char('"')),
|
||||||
|
cut(delimited(
|
||||||
|
char('"'),
|
||||||
|
escaped_transform(none_of(r#""\"#), '\\', string_escape_transforms),
|
||||||
|
char('"'),
|
||||||
|
)),
|
||||||
|
),
|
||||||
))(input)
|
))(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,9 +446,10 @@ 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(Rc::new(s.to_string())) }
|
prefix:identifier()? s:bare_string_literal(){ ExpressionKind::StringLiteral{ s: 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 }
|
||||||
|
@ -17,6 +17,10 @@ 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 }
|
||||||
}
|
}
|
||||||
@ -179,9 +183,12 @@ fn basic_literals() {
|
|||||||
fn string_literals() {
|
fn string_literals() {
|
||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr!(r#""""#, expr(StringLiteral(rc(""))));
|
assert_expr!(r#""""#, expr(strlit("")));
|
||||||
assert_expr!(r#""hello""#, expr(StringLiteral(rc("hello"))));
|
assert_expr!(r#""hello""#, expr(strlit("hello")));
|
||||||
assert_expr!(r#"b"some bytestring""#, expr(StringLiteral(rc("some bytestring"))));
|
assert_expr!(
|
||||||
|
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"))));
|
||||||
}
|
}
|
||||||
@ -296,15 +303,12 @@ fn tuples() {
|
|||||||
use ExpressionKind::*;
|
use ExpressionKind::*;
|
||||||
|
|
||||||
assert_expr!("()", expr(TupleLiteral(vec![])));
|
assert_expr!("()", expr(TupleLiteral(vec![])));
|
||||||
assert_expr!(
|
assert_expr!(r#"("hella", 34)"#, expr(TupleLiteral(vec![expr(strlit("hella")), expr(NatLiteral(34))])));
|
||||||
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(StringLiteral(rc("slough"))),
|
expr(strlit("slough")),
|
||||||
]))
|
]))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -473,7 +477,7 @@ fn lambda_expressions() {
|
|||||||
name: rc("String"),
|
name: rc("String"),
|
||||||
params: vec![]
|
params: vec![]
|
||||||
})),
|
})),
|
||||||
body: vec![stmt(StatementKind::Expression(expr(StringLiteral(rc("q"))))),].into()
|
body: vec![stmt(StatementKind::Expression(expr(strlit("q")))),].into()
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -552,9 +556,8 @@ fn complex_lambdas() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reserved_words() {
|
fn reserved_words() {
|
||||||
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";
|
//TODO assert a good error message for this
|
||||||
assert_fail!("module::item::call()", err);
|
assert_fail!("module::item::call()");
|
||||||
|
|
||||||
assert_expr!("modulek::item", expr(ExpressionKind::Value(qn!(modulek, item))));
|
assert_expr!("modulek::item", expr(ExpressionKind::Value(qn!(modulek, item))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1278,7 +1281,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(StringLiteral(rc("panda"))), expr(BoolLiteral(false)), expr(FloatLiteral(2.2))
|
expr(NatLiteral(45)), expr(strlit("panda")), expr(BoolLiteral(false)), expr(FloatLiteral(2.2))
|
||||||
])))),
|
])))),
|
||||||
body: bx(IfExpressionBody::CondList(vec![
|
body: bx(IfExpressionBody::CondList(vec![
|
||||||
ConditionArm {
|
ConditionArm {
|
||||||
@ -1291,7 +1294,7 @@ if (45, "panda", false, 2.2) {
|
|||||||
]
|
]
|
||||||
)),
|
)),
|
||||||
guard: None,
|
guard: None,
|
||||||
body: vec![stmt(StatementKind::Expression(expr(StringLiteral(rc("no")))))].into(),
|
body: vec![stmt(StatementKind::Expression(expr(strlit("no"))))].into(),
|
||||||
},
|
},
|
||||||
ConditionArm {
|
ConditionArm {
|
||||||
condition: Condition::Pattern(Pattern::TuplePattern(
|
condition: Condition::Pattern(Pattern::TuplePattern(
|
||||||
@ -1303,12 +1306,12 @@ if (45, "panda", false, 2.2) {
|
|||||||
]
|
]
|
||||||
)),
|
)),
|
||||||
guard: None,
|
guard: None,
|
||||||
body: vec![stmt(StatementKind::Expression(expr(StringLiteral(rc("yes")))))].into(),
|
body: vec![stmt(StatementKind::Expression(expr(strlit("yes"))))].into(),
|
||||||
},
|
},
|
||||||
ConditionArm {
|
ConditionArm {
|
||||||
condition: Condition::Pattern(Pattern::Ignored),
|
condition: Condition::Pattern(Pattern::Ignored),
|
||||||
guard: None,
|
guard: None,
|
||||||
body: vec![exst(StringLiteral(rc("maybe")))].into(),
|
body: vec![exst(strlit("maybe"))].into(),
|
||||||
},
|
},
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,8 @@ 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)),
|
||||||
StringLiteral(s) => Expression::Literal(Literal::StringLit(s.clone())),
|
//TODO implement handling string literal prefixes
|
||||||
|
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),
|
||||||
|
Loading…
Reference in New Issue
Block a user