diff options
| -rw-r--r-- | samples/sample1.code | 3 | ||||
| -rw-r--r-- | src/grammar.pest | 2 | ||||
| -rw-r--r-- | src/main.rs | 103 |
3 files changed, 74 insertions, 34 deletions
diff --git a/samples/sample1.code b/samples/sample1.code index 650b0ea..4d70215 100644 --- a/samples/sample1.code +++ b/samples/sample1.code @@ -1 +1,2 @@ -(id id) 1 +id; +id;
\ No newline at end of file diff --git a/src/grammar.pest b/src/grammar.pest index 000ddd5..4fce017 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -3,7 +3,7 @@ WHITESPACE = _{ " " | "\t" | NEWLINE } program = { SOI ~ statement+ ~ EOI } statement = { (definition | expression) } definition = { symbol ~ "=" ~ expression ~ ";"+ } -expression = { (symbol | integer_literal | string_literal | ("(" ~ expression ~ ")"))+ } +expression = { (symbol | integer_literal | string_literal | ("(" ~ expression ~ ")"))+ ~ ";" } integer_literal = @{ "-"? ~ ASCII_DIGIT+ } string_literal = { QUOTATION_MARK ~ (!QUOTATION_MARK ~ ANY)* ~ QUOTATION_MARK } symbol = @{ (ASCII_ALPHA | "_.") ~ (ASCII_ALPHANUMERIC | "-" | "." | "?" | "!")* } diff --git a/src/main.rs b/src/main.rs index 72b60e2..9843aa7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,6 +11,7 @@ mod parser { mod ast { use super::parser::Rule; + use std::rc::Rc; pub fn from_parse_tree(parse_tree: &mut pest::iterators::Pairs<Rule>) -> Program { let root = parse_tree.next().unwrap(); @@ -37,9 +38,9 @@ mod ast { pub enum Statement { Definition { symbol: Symbol, - expression: Expression, + expression: Rc<Expression>, }, - Expression(Expression), + Expression(Rc<Expression>), } impl Statement { @@ -57,7 +58,7 @@ mod ast { Statement::Definition { symbol: String::from(symbol), - expression: expression_inners, + expression: expression_vec_to_tuple(&expression_inners), } } @@ -68,19 +69,19 @@ mod ast { .into_inner() .map(ExpressionInner::from_pair) .collect(); - Statement::Expression(expression_inners) + Statement::Expression(expression_vec_to_tuple(&expression_inners)) } rule => panic!("[ast] can't make a statement from {:#?}", rule), } } } - #[derive(Debug)] + #[derive(Debug, Clone)] pub enum ExpressionInner { Symbol(Symbol), IntegerLiteral(IntegerLiteral), StringLiteral(StringLiteral), - Expression(Expression), + Expression(Rc<Expression>), } impl ExpressionInner { @@ -101,14 +102,26 @@ mod ast { Rule::expression => { let expression_inners: Vec<ExpressionInner> = pair.into_inner().map(ExpressionInner::from_pair).collect(); - ExpressionInner::Expression(expression_inners) + ExpressionInner::Expression(expression_vec_to_tuple(&expression_inners)) } rule => panic!("[ast] can't make an expression element from {:#?}", rule), } } } - pub type Expression = Vec<ExpressionInner>; + #[derive(Debug)] + pub enum Expression { + Unary(ExpressionInner), + Binary(ExpressionInner, ExpressionInner), + } + + fn expression_vec_to_tuple(v: &Vec<ExpressionInner>) -> Rc<Expression> { + match v.len() { + 1 => Rc::new(Expression::Unary(v[0].clone())), + 2 => Rc::new(Expression::Binary(v[0].clone(), v[1].clone())), + _ => todo!("[ast] expr tree generation"), + } + } pub type IntegerLiteral = i64; fn integer_from_pair(pair: pest::iterators::Pair<Rule>) -> i64 { @@ -178,21 +191,11 @@ mod runtime { symbol_table: &HashMap<String, Rc<Value>>, expression: &ast::Expression, ) -> Rc<Value> { - // println!("[runtime] evaluating expression"); - let head = &expression[0]; - let tail = &expression[1..]; - let arity = tail.len(); - match head { - ast::ExpressionInner::IntegerLiteral(value) => match arity { - 0 => Rc::new(Value::Integer(*value)), - _ => panic!("[runtime] cannot apply integer: {}", value), - }, - ast::ExpressionInner::StringLiteral(value) => match arity { - 0 => Rc::new(Value::String(value.clone())), - _ => panic!("[runtime] cannot apply string: {}", value), - }, - ast::ExpressionInner::Symbol(value) => match arity { - 0 => { + match expression { + ast::Expression::Unary(inner) => match inner { + ast::ExpressionInner::IntegerLiteral(value) => Rc::new(Value::Integer(*value)), + ast::ExpressionInner::StringLiteral(value) => Rc::new(Value::String(value.clone())), + ast::ExpressionInner::Symbol(value) => { let builtin_value = try_evaluate_builtin(value); if builtin_value.is_some() { return Rc::new(builtin_value.unwrap()); @@ -204,19 +207,55 @@ mod runtime { return lookup_rc.clone(); } - Rc::new(Value::String(String::from("dummy value"))) + panic!("[runtime] symbol not defined: {:#?}", value); } - 1 => { - // let arg = &tail[0]; - // let applied = try_apply_function(value, arg, None); - panic!("should apply function here!") + ast::ExpressionInner::Expression(value_rc) => { + let sub_expr = &**value_rc; + evaluate_expr(symbol_table, sub_expr) } - _ => unreachable!( - "[runtime] expression arity >= 2! there must be an error in AST generation" - ), }, - ast::ExpressionInner::Expression(expression) => evaluate_expr(symbol_table, expression), + ast::Expression::Binary(inner1, inner2) => todo!("[runtime] binary expressions"), } + + // println!("[runtime] evaluating expression"); + // let head = &expression[0]; + // let tail = &expression[1..]; + // let arity = tail.len(); + // match head { + // ast::ExpressionInner::IntegerLiteral(value) => match arity { + // 0 => Rc::new(Value::Integer(*value)), + // _ => panic!("[runtime] cannot apply integer: {}", value), + // }, + // ast::ExpressionInner::StringLiteral(value) => match arity { + // 0 => Rc::new(Value::String(value.clone())), + // _ => panic!("[runtime] cannot apply string: {}", value), + // }, + // ast::ExpressionInner::Symbol(value) => match arity { + // 0 => { + // let builtin_value = try_evaluate_builtin(value); + // if builtin_value.is_some() { + // return Rc::new(builtin_value.unwrap()); + // } + + // let table_lookup_value = symbol_table.get(value); + // if table_lookup_value.is_some() { + // let lookup_rc = table_lookup_value.unwrap(); + // return lookup_rc.clone(); + // } + + // Rc::new(Value::String(String::from("dummy value"))) + // } + // 1 => { + // // let arg = &tail[0]; + // // let applied = try_apply_function(value, arg, None); + // panic!("should apply function here!") + // } + // _ => unreachable!( + // "[runtime] expression arity >= 2! there must be an error in AST generation" + // ), + // }, + // ast::ExpressionInner::Expression(expression) => evaluate_expr(symbol_table, expression), + // } } pub fn evaluate(program: &ast::Program) { |
