Broken, but compiling, move to new if paradigm
This commit is contained in:
parent
ba4cd9da39
commit
f2dce38647
@ -93,7 +93,10 @@ pub enum ExpressionType {
|
||||
indexee: Box<Expression>,
|
||||
indexers: Vec<Expression>,
|
||||
},
|
||||
IfExpression(Box<Expression>, Block, Option<Block>),
|
||||
IfExpression {
|
||||
discriminator: Box<Discriminator>,
|
||||
body: Box<IfExpressionBody>,
|
||||
},
|
||||
WhileExpression {
|
||||
condition: Option<Box<Expression>>,
|
||||
body: Block,
|
||||
@ -108,6 +111,28 @@ pub enum ExpressionType {
|
||||
},
|
||||
ListLiteral(Vec<Expression>),
|
||||
}
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Discriminator {
|
||||
Simple(Expression),
|
||||
BinOp(Expression, BinOp)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum IfExpressionBody {
|
||||
SimpleConditional(Block, Option<Block>),
|
||||
GuardList(Vec<Guard>)
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Guard {
|
||||
pat: Pattern,
|
||||
body: Block,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Pattern {
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Enumerator {
|
||||
|
@ -97,6 +97,8 @@ int_literal = ('0x' | '0b') digits
|
||||
float_literal := digits ('.' digits)
|
||||
digits := (DIGIT_GROUP underscore)+
|
||||
|
||||
/* OLD OBSOLETE */
|
||||
|
||||
/* Expression - If */
|
||||
if_expr := 'if' expression block else_clause
|
||||
else_clause := ε | 'else' block
|
||||
@ -107,6 +109,13 @@ match_body := '{' (match_arm)* '}'
|
||||
match_arm := pattern '=>' expression
|
||||
pattern := identifier //TODO NOT DONE
|
||||
|
||||
/* NEW GOOD */
|
||||
|
||||
/* Expression - If */
|
||||
if_expr := 'if' discriminator ('then' condititional | guard_block)
|
||||
discriminator := modified_precedence_expression
|
||||
conditional := block else_clause
|
||||
else_clause := ε | 'else' block
|
||||
|
||||
/* Expression - While */
|
||||
while_expr := 'while' while_cond '{' (statement delimiter)* '}'
|
||||
@ -618,15 +627,35 @@ impl Parser {
|
||||
|
||||
parse_method!(if_expr(&mut self) -> ParseResult<Expression> {
|
||||
expect!(self, Keyword(Kw::If));
|
||||
let condition = {
|
||||
let discriminator = Box::new({
|
||||
self.restrictions.no_struct_literal = true;
|
||||
let x = self.expression();
|
||||
let x = self.discriminator();
|
||||
self.restrictions.no_struct_literal = false;
|
||||
x?
|
||||
};
|
||||
let then_clause = self.block()?;
|
||||
});
|
||||
|
||||
let body = Box::new(if let Keyword(Kw::Then) = self.peek() {
|
||||
self.conditional()?
|
||||
} else {
|
||||
self.guard_block()?
|
||||
});
|
||||
|
||||
Ok(Expression(ExpressionType::IfExpression { discriminator, body }, None))
|
||||
});
|
||||
|
||||
parse_method!(discriminator(&mut self) -> ParseResult<Discriminator> {
|
||||
Ok(Discriminator::Simple(self.expression()?)) //TODO make proper
|
||||
});
|
||||
|
||||
parse_method!(conditional(&mut self) -> ParseResult<IfExpressionBody> {
|
||||
expect!(self, Keyword(Kw::Then));
|
||||
let then_clause = self.block()?; //TODO should be block_or_expr
|
||||
let else_clause = self.else_clause()?;
|
||||
Ok(Expression(ExpressionType::IfExpression(bx!(condition), then_clause, else_clause), None))
|
||||
Ok(IfExpressionBody::SimpleConditional(then_clause, else_clause))
|
||||
});
|
||||
|
||||
parse_method!(guard_block(&mut self) -> ParseResult<IfExpressionBody> {
|
||||
ParseError::new("Rest of if not done")
|
||||
});
|
||||
|
||||
parse_method!(else_clause(&mut self) -> ParseResult<Option<Block>> {
|
||||
@ -1094,13 +1123,14 @@ fn a(x) {
|
||||
|
||||
#[test]
|
||||
fn parsing_block_expressions() {
|
||||
parse_test!("if a() { b(); c() }", AST(vec![exprstatement!(
|
||||
/*
|
||||
parse_test!("if a() then { b(); c() }", AST(vec![exprstatement!(
|
||||
IfExpression(bx!(ex!(Call { f: bx!(ex!(val!("a"))), arguments: vec![]})),
|
||||
vec![exprstatement!(Call { f: bx!(ex!(val!("b"))), arguments: vec![]}), exprstatement!(Call { f: bx!(ex!(val!("c"))), arguments: vec![] })],
|
||||
None)
|
||||
)]));
|
||||
parse_test!(r#"
|
||||
if true {
|
||||
if true then {
|
||||
const a = 10
|
||||
b
|
||||
} else {
|
||||
@ -1123,6 +1153,7 @@ fn a(x) {
|
||||
Some(vec![exprstatement!(val!("c"))])))]));
|
||||
|
||||
parse_error!("if A {a: 1} { b } else { c }");
|
||||
*/
|
||||
}
|
||||
#[test]
|
||||
fn parsing_interfaces() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use ast::{AST, Statement, Expression, Declaration};
|
||||
use ast::{AST, Statement, Expression, Declaration, Discriminator};
|
||||
use symbol_table::{Symbol, SymbolSpec, SymbolTable};
|
||||
use builtin::{BinOp, PrefixOp};
|
||||
|
||||
@ -112,6 +112,15 @@ impl Expression {
|
||||
args: arguments.iter().map(|arg| arg.reduce(symbol_table)).collect(),
|
||||
},
|
||||
TupleLiteral(exprs) => Expr::Tuple(exprs.iter().map(|e| e.reduce(symbol_table)).collect()),
|
||||
IfExpression { discriminator, body } => {
|
||||
let cond = Box::new(match **discriminator {
|
||||
Discriminator::Simple(ref expr) => expr.reduce(symbol_table),
|
||||
_ => panic!(),
|
||||
});
|
||||
|
||||
Expr::Conditional { cond, then_clause: vec![], else_clause: vec![] }
|
||||
},
|
||||
/*
|
||||
IfExpression(cond, then_clause, else_clause) => Expr::Conditional {
|
||||
cond: Box::new((**cond).reduce(symbol_table)),
|
||||
then_clause: then_clause.iter().map(|expr| expr.reduce(symbol_table)).collect(),
|
||||
@ -120,6 +129,7 @@ impl Expression {
|
||||
Some(stmts) => stmts.iter().map(|expr| expr.reduce(symbol_table)).collect(),
|
||||
}
|
||||
},
|
||||
*/
|
||||
_ => Expr::UnimplementedSigilValue,
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user