Skip to content

Commit

Permalink
builtin functions now work and i made builtin functions a type of typ…
Browse files Browse the repository at this point in the history
…e and data
  • Loading branch information
ludverse committed Feb 22, 2024
1 parent ebb3435 commit bbf9953
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 32 deletions.
7 changes: 4 additions & 3 deletions example.ox
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
let hi = "so";
let b = "no";
hi.b = "cardi";
fn hi() {
"ok";
}
print(hi());

26 changes: 18 additions & 8 deletions src/builtin/mod.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,41 @@
use crate::data::Data;
use crate::errors::ParseErrKind;
use crate::memory::Memory;
use crate::types::Type;

pub mod print;

const BUILTIN_FUNCTIONS: [(&'static str, Type, Data); 1] = [
("print", Type::BuiltinFn(BuiltinFn::Print), Data::BuiltinFn(BuiltinFn::Print)),
];

#[derive(Debug, Clone, PartialEq)]
pub enum BuiltinFunc {
pub enum BuiltinFn {
Print,
}

impl BuiltinFunc {
pub fn from_name(name: &String) -> Option<BuiltinFunc> {
match &name[..] {
"print" => Some(BuiltinFunc::Print),
_ => None
impl BuiltinFn {
pub fn populate_memory(memory: &mut Memory<Data>) {
for (name, _, builtin_fn_data) in BUILTIN_FUNCTIONS {
memory.insert(String::from(name), builtin_fn_data);
}
}

pub fn populate_sim_memory(memory: &mut Memory<Type>) {
for (name, builtin_fn_type, _) in BUILTIN_FUNCTIONS {
memory.insert(String::from(name), builtin_fn_type);
}
}

pub fn type_check(&self, args: Vec<Type>) -> Result<Type, ParseErrKind>{
match self {
BuiltinFunc::Print => print::type_check(args)
BuiltinFn::Print => print::type_check(args)
}
}

pub fn eval(&self, args: Vec<Data>) -> Data {
match self {
BuiltinFunc::Print => print::eval(args)
BuiltinFn::Print => print::eval(args)
}
}
}
5 changes: 4 additions & 1 deletion src/data/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fmt::Debug;
use crate::builtin::BuiltinFn;
use crate::errors::{ParseErr, ParseErrKind};
use crate::interpreter::Interpreter;
use crate::operations::Operation;
Expand All @@ -13,16 +14,18 @@ pub enum Data {
Number(f64),
Bool(bool),
Fn(FunctionDeclaration),
BuiltinFn(BuiltinFn),
TempNil // just a temporary null value in the meantime as we dont have empty tuples yet
}

impl Data {
pub fn get_type(&self) -> Type {
match &self {
match self {
Data::String(val) => Type::String,
Data::Number(val) => Type::Number,
Data::Bool(val) => Type::Bool,
Data::Fn(val) => Type::Fn { args_types: val.args.clone(), return_type: val.return_type.clone() },
Data::BuiltinFn(builtin_fn) => Type::BuiltinFn(builtin_fn.clone()),
Data::TempNil => Type::TempNil
}
}
Expand Down
53 changes: 41 additions & 12 deletions src/expressions/call.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::builtin::BuiltinFunc;
use crate::builtin::BuiltinFn;
use crate::data::Data;
use crate::errors::{ParseErrKind, ParseErr};
use crate::expressions::{Expr, Evaluable};
Expand Down Expand Up @@ -27,36 +27,34 @@ impl Evaluable for ExprCall {
fn typ(&self, parser: &Parser) -> Result<Type, ParseErrKind> {
let mangled_path = self.path.mangle_path()?;

let fn_type = self.path.typ(parser)?;
let args: Vec<_> = self.args.iter()
.map(|arg_expr| arg_expr.typ(parser).unwrap()) // IDK how to not unwrap this and error
// handle this
.collect();

if let Some(builtin) = BuiltinFunc::from_name(&mangled_path) {
return Ok(builtin.type_check(args)?)
}

if let Type::Fn { args_types, return_type } = self.path.typ(parser)? {
if let Type::Fn { args_types, return_type } = fn_type {
// TODO: check for that args types and args have same type

return Ok(*return_type)
}

if let Type::BuiltinFn(builtin) = fn_type {
return builtin.type_check(args);
}

unreachable!();
}

fn eval(&self, interpreter: &mut Interpreter) -> Data {
let mangled_path = self.path.mangle_path().unwrap();

let fn_data = self.path.eval(interpreter);
let args: Vec<_> = self.args.iter()
.map(|arg_expr| arg_expr.eval(interpreter))
.collect();

if let Some(builtin) = BuiltinFunc::from_name(&mangled_path) {
return builtin.eval(args);
}

if let Data::Fn(fn_decl) = self.path.eval(interpreter) {
if let Data::Fn(fn_decl) = fn_data {
interpreter.memory.push_scope();

for (i, arg_data) in args.iter().enumerate() {
Expand All @@ -70,6 +68,37 @@ impl Evaluable for ExprCall {
return res;
}

panic!("should have already been caught by the parser")
if let Data::BuiltinFn(builtin_fn) = fn_data {
return builtin_fn.eval(args);
}

unreachable!();
}
}

pub fn parse(parser: &mut Parser, first_token: &Token, expr: Expr) -> Result<Expr, ParseErr> {
let mut args = vec![];

destructive_loop!({
let next_token = parser.collector.next();
match &next_token.token {
TokenType::RightParen => break,
_ => ()
}

// TODO: prob explain to the user that it expects a rightparent too but current error
// handler doesn't support that so ill fix it in post
let arg_expr = Expr::parse_expr(parser, next_token)?;

args.push(Box::new(arg_expr));

let next_token = parser.collector.next();
match &next_token.token {
TokenType::Comma => continue,
TokenType::RightParen => break,
_ => return Err(parser.unexpected_token(next_token, "Comma or RightParen"))
}
});

Ok(Expr::Call(ExprCall::new(Box::new(expr), args)))
}
9 changes: 3 additions & 6 deletions src/expressions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,23 +141,20 @@ impl Expr {
let next_token = parser.collector.next();
match &next_token.token {
TokenType::Identifier(name) => {

expr = Expr::Field(ExprField::new(name.to_string(), Some(Box::new(expr))));
expr_type = map_err_token(expr.typ(parser), next_token)?;

},
_ => return Err(parser.unexpected_token(next_token, "field"))
}

},
TokenType::LeftBrace => {
// indexing
},
TokenType::LeftParen => expr = call::parse(parser, next_token, expr)?,
_ => {
parser.collector.back();
break
}
}

expr_type = map_err_token(expr.typ(parser), next_token)?;
}
});

Expand Down
7 changes: 6 additions & 1 deletion src/interpreter/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::builtin::BuiltinFn;
use crate::memory::Memory;
use crate::parser::Program;
use crate::data::Data;
Expand All @@ -9,9 +10,13 @@ pub struct Interpreter {

impl Interpreter {
pub fn new(program: Program) -> Interpreter {
let mut memory = Memory::new();

BuiltinFn::populate_memory(&mut memory);

Interpreter {
program,
memory: Memory::new()
memory,
}
}

Expand Down
7 changes: 6 additions & 1 deletion src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::HashMap;

use crate::builtin::BuiltinFn;
use crate::memory::Memory;
use crate::tokenizer::{Token, TokenType};
use crate::statements::Statement;
Expand Down Expand Up @@ -29,9 +30,13 @@ pub struct Parser<'a> {

impl<'a> Parser<'a> {
pub fn new(collector: TokenCollector<'a>) -> Parser<'a> {
let mut sim_memory = Memory::new();

BuiltinFn::populate_sim_memory(&mut sim_memory);

Parser {
collector,
sim_memory: Memory::new()
sim_memory,
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use crate::builtin::BuiltinFn;

#[derive(Debug, Clone, PartialEq)]
pub enum Type {
String,
Expand All @@ -7,6 +9,7 @@ pub enum Type {
args_types: Vec<(String, Type)>,
return_type: Box<Type>
},
BuiltinFn(BuiltinFn),
TempNil
}

Expand Down

0 comments on commit bbf9953

Please sign in to comment.