Implement inefficient and not useful functions

- Function calls are inefficient
- Function parameters are passed in the global vartable (which is pretty
  bad)
This commit is contained in:
Daniel M 2022-02-03 13:17:06 +01:00
parent 85339db25e
commit 638610d310
3 changed files with 65 additions and 4 deletions

View File

@ -118,7 +118,7 @@ pub enum Statement {
Loop(Loop),
If(If),
Print(Expression),
FunDecl(Vec<(String, Expression)>),
FunDecl(String, Vec<String>, Ast),
}
#[derive(Debug, PartialEq, Eq, Clone, Default)]

View File

@ -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<String, Value>,
funtable: HashMap<String, RefCell<(Vec<String>, 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)
}
}
}

View File

@ -54,6 +54,49 @@ impl<T: Iterator<Item = Token>> Parser<T> {
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());