Skip to content

Commit

Permalink
basic function calling works, but parent relationshop for environment…
Browse files Browse the repository at this point in the history
…s is broken
  • Loading branch information
nulluser committed Jun 1, 2024
1 parent da55725 commit e5c8167
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/backend/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{mk_bool, mk_native_fn, mk_null};

use super::native_fn::{native_println, native_time};

#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub struct Environment<'a> {
values: HashMap<String, Val>,
is_mutable: HashSet<String>,
Expand Down
33 changes: 27 additions & 6 deletions src/backend/eval/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ use std::collections::HashMap;
use crate::{
backend::{
environment::Environment,
values::{FloatVal, IntegerVal, ObjectVal, ToFloat, Val},
interpreter::evaluate,
values::{FloatVal, IntegerVal, NullVal, ObjectVal, ToFloat, Val},
},
frontend::ast::{BinaryOp, Expr, Literal, Property},
mk_float, mk_integer,
mk_float, mk_integer, mk_null,
};

pub fn evaluate_expr(expr: Expr, env: &mut Environment) -> Val {
Expand Down Expand Up @@ -61,11 +62,31 @@ pub fn evaluate_call_expr(args: Vec<Expr>, caller: Expr, env: &mut Environment)
.map(|expr| evaluate_expr(expr, env))
.collect();
let function = evaluate_expr(caller, env);
let callable = match function {
Val::NativeFunction(callable) => callable.call,
_ => panic!("Cannot call value that is not a function: {:?}", function),
match &function {
Val::NativeFunction(callable) => return (callable.call)(evaluated_args, env),
Val::Function(fn_value) => {
let mut scope = Environment::new_with_parent(env);
println!("{:#?}", scope);
for (i, _) in evaluated_args
.iter()
.enumerate()
.take(fn_value.parameters.len())
{
// TODO: Check the bounds here.
// Verify arity of function.
let varname = &fn_value.parameters[i];
let arg = &evaluated_args[i];
scope.declare_var(varname, arg.clone(), false);
}
let mut result: Val = mk_null!();
for stmt in &fn_value.body {
result = evaluate(stmt.clone(), &mut scope)
}
return result;
}
_ => {}
};
callable(evaluated_args, env)
panic!("Cannot call value that is not a function: {:?}", function);
}

pub fn evaluate_binary_op(op: BinaryOp, left: Expr, right: Expr, env: &mut Environment) -> Val {
Expand Down
24 changes: 22 additions & 2 deletions src/backend/eval/statements.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::{
backend::{environment::Environment, values::NullVal, values::Val},
frontend::ast::Expr,
backend::{
environment::Environment,
values::{FunctionVal, NullVal, Val},
},
frontend::ast::{Expr, Stmt},
mk_null,
};

Expand All @@ -20,3 +23,20 @@ pub fn evaluate_declare_var(

env.declare_var(&name, value, is_mutable)
}

pub fn evaluate_declare_fn(
parameters: Vec<String>,
name: String,
body: Vec<Stmt>,
is_async: bool,
env: &mut Environment,
) -> Val {
let function: Val = Val::Function(FunctionVal {
name: name.clone(),
parameters,
body,
is_async,
});

env.declare_var(&name, function, false)
}
7 changes: 4 additions & 3 deletions src/backend/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::frontend::ast::Stmt;

use super::environment::Environment;
use super::eval::expressions::evaluate_expr;
use super::eval::statements::evaluate_declare_var;
use super::eval::statements::{evaluate_declare_fn, evaluate_declare_var};
use super::values::Val;

pub fn evaluate(stmt: Stmt, env: &mut Environment) -> Val {
Expand All @@ -15,7 +15,8 @@ pub fn evaluate(stmt: Stmt, env: &mut Environment) -> Val {
}
Stmt::ReturnStmt(_) => unimplemented!(),
Stmt::IfStmt(_, _, _) => unimplemented!(),
Stmt::FunctionDeclaration(parameters, name, body, is_async) => todo!(),
// Handle other statement types...
Stmt::FunctionDeclaration(parameters, name, body, is_async) => {
evaluate_declare_fn(parameters, name, body, is_async, env)
} // Handle other statement types...
}
}
9 changes: 6 additions & 3 deletions src/backend/values.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::collections::HashMap;

use crate::frontend::ast::Stmt;

use super::environment::Environment;

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -95,9 +97,10 @@ impl RuntimeVal for NativeFunctionVal {

#[derive(Debug, PartialEq, Clone)]
pub struct FunctionVal {
name: String,
parameters: Vec<String>,
declaration_env: &Environment,
pub name: String,
pub parameters: Vec<String>,
pub body: Vec<Stmt>,
pub is_async: bool,
}

impl RuntimeVal for FunctionVal {
Expand Down
12 changes: 6 additions & 6 deletions src/frontend/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ impl Program {
}
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Clone)]
pub enum Expr {
Literal(Literal),
Identifier(String),
Expand All @@ -38,7 +38,7 @@ impl std::fmt::Display for Expr {
}
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Clone)]
pub enum Stmt {
ExprStmt(Expr),
DeclareStmt(String, bool, Option<Expr>), // Name, is_mutable, expr
Expand All @@ -47,7 +47,7 @@ pub enum Stmt {
IfStmt(Expr, Vec<Stmt>, Vec<Stmt>),
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Clone)]
pub enum Literal {
Integer(i64),
Float(f64),
Expand All @@ -56,13 +56,13 @@ pub enum Literal {
// Other literal types...
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Clone)]
pub struct Property {
pub key: String,
pub value: Option<Expr>,
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Clone)]
pub enum BinaryOp {
Add,
Subtract,
Expand Down Expand Up @@ -100,7 +100,7 @@ impl From<Operator> for BinaryOp {
}
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Clone)]
pub enum UnaryOp {
Negate,
// Other unary operators...
Expand Down

0 comments on commit e5c8167

Please sign in to comment.