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:
parent
85339db25e
commit
638610d310
@ -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)]
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user