From 638610d31058deae8e05a45c6e164f17139a17b6 Mon Sep 17 00:00:00 2001 From: Daniel M Date: Thu, 3 Feb 2022 13:17:06 +0100 Subject: [PATCH] Implement inefficient and not useful functions - Function calls are inefficient - Function parameters are passed in the global vartable (which is pretty bad) --- src/ast.rs | 2 +- src/interpreter.rs | 24 +++++++++++++++++++++--- src/parser.rs | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index 8018c18..f2e98f9 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -118,7 +118,7 @@ pub enum Statement { Loop(Loop), If(If), Print(Expression), - FunDecl(Vec<(String, Expression)>), + FunDecl(String, Vec, Ast), } #[derive(Debug, PartialEq, Eq, Clone, Default)] diff --git a/src/interpreter.rs b/src/interpreter.rs index 70c56e3..ccc01ed 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, fmt::Display, rc::Rc}; +use std::{collections::HashMap, fmt::Display, rc::Rc, cell::RefCell}; use crate::{ast::{Expression, BinOpType, UnOpType, Ast, Statement, If}, parser::parse, lexer::lex}; @@ -11,12 +11,14 @@ pub enum Value { pub struct Interpreter { // Variable table stores the runtime values of variables vartable: HashMap, + funtable: HashMap, Ast)>>, } impl Interpreter { pub fn new() -> Self { Self { vartable: HashMap::new(), + funtable: HashMap::new(), } } @@ -68,7 +70,9 @@ impl Interpreter { self.run(body_true); } } - Statement::FunDecl(_) => todo!(), + Statement::FunDecl(name, args, body) => { + self.funtable.insert(name.clone(), (args.clone(), body.clone()).into()); + } } } @@ -81,7 +85,21 @@ impl Interpreter { Expression::BinOp(bo, lhs, rhs) => self.resolve_binop(bo, lhs, rhs), Expression::UnOp(uo, operand) => self.resolve_unop(uo, operand), Expression::Var(name) => self.resolve_var(name), - Expression::FunCall(_, _) => todo!(), + Expression::FunCall(name, args) => { + let fun = self.funtable.get(name).expect("Function not declared").clone(); + for i in 0 .. args.len() { + let val = self.resolve_expr(&args[i]); + self.vartable.insert(fun.borrow().0[i].clone(), val); + } + + if fun.borrow().0.len() != args.len() { + panic!("Invalid number of arguments for function"); + } + + self.run(&fun.borrow().1); + + Value::I64(0) + } } } diff --git a/src/parser.rs b/src/parser.rs index ff60fe4..713ee1c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -54,6 +54,49 @@ impl> Parser { Token::If => Statement::If(self.parse_if()), + Token::Fun => { + self.next(); + + let name = match self.next() { + Token::Ident(name) => name, + _ => panic!("Error lexing function: Expected ident token"), + }; + + let mut args = Vec::new(); + + if !matches!(self.next(), Token::LParen) { + panic!("Expected opening parenthesis"); + } + + while self.peek() != &Token::RParen { + let argname = match self.next() { + Token::Ident(argname) => argname, + _ => panic!("Error lexing function: Expected ident token for argname"), + }; + + args.push(argname); + + if self.peek() == &Token::Comma { + self.next(); + } + + } + + self.next(); + + if !matches!(self.next(), Token::LBraces) { + panic!("Expected opening braces"); + } + + let body = self.parse(); + + if !matches!(self.next(), Token::RBraces) { + panic!("Expected closing braces"); + } + + Statement::FunDecl(name, args, body) + } + // If it is not a loop, try to lex as an expression _ => { let stmt = Statement::Expr(self.parse_expr());