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),
|
Loop(Loop),
|
||||||
If(If),
|
If(If),
|
||||||
Print(Expression),
|
Print(Expression),
|
||||||
FunDecl(Vec<(String, Expression)>),
|
FunDecl(String, Vec<String>, Ast),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Default)]
|
#[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};
|
use crate::{ast::{Expression, BinOpType, UnOpType, Ast, Statement, If}, parser::parse, lexer::lex};
|
||||||
|
|
||||||
@ -11,12 +11,14 @@ pub enum Value {
|
|||||||
pub struct Interpreter {
|
pub struct Interpreter {
|
||||||
// Variable table stores the runtime values of variables
|
// Variable table stores the runtime values of variables
|
||||||
vartable: HashMap<String, Value>,
|
vartable: HashMap<String, Value>,
|
||||||
|
funtable: HashMap<String, RefCell<(Vec<String>, Ast)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Interpreter {
|
impl Interpreter {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
vartable: HashMap::new(),
|
vartable: HashMap::new(),
|
||||||
|
funtable: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +70,9 @@ impl Interpreter {
|
|||||||
self.run(body_true);
|
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::BinOp(bo, lhs, rhs) => self.resolve_binop(bo, lhs, rhs),
|
||||||
Expression::UnOp(uo, operand) => self.resolve_unop(uo, operand),
|
Expression::UnOp(uo, operand) => self.resolve_unop(uo, operand),
|
||||||
Expression::Var(name) => self.resolve_var(name),
|
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::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
|
// If it is not a loop, try to lex as an expression
|
||||||
_ => {
|
_ => {
|
||||||
let stmt = Statement::Expr(self.parse_expr());
|
let stmt = Statement::Expr(self.parse_expr());
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user