Broken, but compiling, move to new if paradigm

This commit is contained in:
greg 2018-06-19 02:05:25 -07:00
parent ba4cd9da39
commit f2dce38647
3 changed files with 75 additions and 9 deletions

View File

@ -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 {

View File

@ -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() {

View File

@ -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,
}
}