From cd7ccd1b1b9185e1d233a22d0d3314783b378728 Mon Sep 17 00:00:00 2001 From: TheCPP Date: Fri, 23 Aug 2024 17:41:18 +0200 Subject: [PATCH] [BUG] reopining #8 --- tools/simplelang/example.sl | 14 ++++++-- tools/simplelang/lexer.rs | 15 ++++++-- tools/simplelang/semnatic.rs | 68 +++++++++++++++++++++++++----------- 3 files changed, 71 insertions(+), 26 deletions(-) diff --git a/tools/simplelang/example.sl b/tools/simplelang/example.sl index 214083da..ba840da8 100644 --- a/tools/simplelang/example.sl +++ b/tools/simplelang/example.sl @@ -15,12 +15,20 @@ HOW TO RUN: import with (fmt: string, ...) printf // printf from libc +with (a: u64, b: u64) add: { + return a + b; +} + extern with () main: { - printf("Hello World!\n"); + var x: string = "Hello World!"; + + printf(x); - var x: u32 = 5; + var a: u64 = 1; + var b: u64 = 0xd; // 0xd -> 13 + var expected: u64 = a + b; - printf("%d = %d", x, 5); + printf("add(%d, %d) = %d # expected: %d", a, b, add(a, b), expected); return 0; } \ No newline at end of file diff --git a/tools/simplelang/lexer.rs b/tools/simplelang/lexer.rs index 25a5e9cc..d921448f 100644 --- a/tools/simplelang/lexer.rs +++ b/tools/simplelang/lexer.rs @@ -13,7 +13,7 @@ pub enum LexingError { impl Display for LexingError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - LexingError::UnexpectedCharacter(ch) => write!(f, "Error: Unexpected character '{}'", ch), + LexingError::UnexpectedCharacter(ch) => write!(f, "unexpected character '{}'", ch), _ => write!(f, ""), } } @@ -37,7 +37,18 @@ pub enum Token { #[regex(r#""[^"]*""#, |lex| unescape(&lex.slice().to_string().replace("\"", "")).unwrap())] String(String), - #[regex("[0-9_]+", priority = 3, callback = |lex| lex.slice().parse())] + #[regex(r"(0x[0-9a-fA-F]+|0b[01]+|\d+)", priority = 3, callback = |lex| { + let string = lex.slice(); + if string.starts_with("0x") { + i64::from_str_radix(&string.replace("0x", ""), 16) + } else if string.starts_with("0b") { + i64::from_str_radix(&string.replace("0b", ""), 2) + } else if string.starts_with("-") { + Ok(-(string.replace("-", "").parse::()?)) + } else { + string.parse() + } + })] Number(i64), #[token("with")] diff --git a/tools/simplelang/semnatic.rs b/tools/simplelang/semnatic.rs index 901837ba..51897980 100644 --- a/tools/simplelang/semnatic.rs +++ b/tools/simplelang/semnatic.rs @@ -29,6 +29,14 @@ impl Semnatic { } pub fn analyze(&mut self) { + for stmt in self.stmts.clone() { + if let Statement::Fn(func) = stmt { + self.add_func(&func); + } else { + err!(self.error, "expected function statement found {:?}", stmt); + } + } + while let Some(stmt) = self.stmts.pop_front() { if let Statement::Fn(func) = stmt { self.analyze_func(&func); @@ -49,12 +57,46 @@ impl Semnatic { } fn analyze_func(&mut self, func: &FnStmt) { + let mut vars = HashMap::new(); + + for arg in &func.args { + match arg { + Expr::Var(var) => { + vars.insert(var.0.to_string(), var.1); + }, + _ => { + err!(self.error, "expected variables as function args not terms/calls"); + return; + } + } + } + + let mut returned = func.import; + + for stmt in &func.body { + if returned { + warn!("unreachable code after return statemant"); + }; + + if let Statement::Ret(_) = stmt { + returned = true; + } + + self.analyze_stmt(stmt, &mut vars); + } + + if !(returned) { + err!(self.error, "function {:?} needs to return {:?} but found nothing", func.name, "to be implemented");//func.ret); + } + + } + + fn add_func(&mut self, func: &FnStmt) { if self.funcs.contains_key(&func.name) { err!(self.error, "func {} defined twice", func.name); return; } - let mut vars = HashMap::new(); let mut args = vec![]; if func.import && func.body.len() > 0 { @@ -69,8 +111,7 @@ impl Semnatic { for arg in &func.args { match arg { - Expr::Var(var) => { - vars.insert(var.0.to_string(), var.1); + Expr::Var(var) => { args.push(Expr::Var(var.clone())); }, _ => { @@ -90,24 +131,7 @@ impl Semnatic { return; } - let mut returned = false; // if encountered return node - - for stmt in &func.body { - if returned { - warn!("unreachable code after return statemant"); - }; - - if let Statement::Ret(_) = stmt { - returned = true; - } - - self.analyze_stmt(stmt, &mut vars); - } - - if !(returned) { - err!(self.error, "function {:?} needs to return {:?} but found nothing", func.name, "to be implemented");//func.ret); - } - + self.funcs.insert(func.name.to_string(), (args, vec![], false)); } fn analyze_expr(&mut self, expr: &Expr, vars: &mut HashMap>) { @@ -174,6 +198,8 @@ impl Semnatic { self.analyze_expr(&left, vars); self.analyze_expr(&right, vars); + + self.in_binary = false; } fn analyze_call(&mut self, call: &CallStmt, vars: &mut HashMap>) {