From dd1b6af259e034f7421fd6b0877c25ff632d7e68 Mon Sep 17 00:00:00 2001 From: MCorange Date: Thu, 12 Feb 2026 23:26:59 +0200 Subject: [PATCH] Fix bunch of bugs, endianess of numbers seems to befucked, i have no idea why --- libbeaker.so | Bin 0 -> 47688 bytes src/cli.rs | 4 +++ src/common/loc.rs | 8 ++++- src/parser/ast/literal.rs | 7 +++-- src/parser/ast/statement.rs | 41 +++++++++++++++++++------ src/parser/ast/typ.rs | 19 ++++++++++-- src/parser/expr.rs | 21 +++++++++++-- src/parser/stat.rs | 19 +++++++++--- src/parser/typ.rs | 36 +++++++++++++++++++++- src/targets/mod.rs | 5 ++- src/targets/x86_64/asmgen/linux/mod.rs | 16 +++++++--- src/tokeniser/mod.rs | 1 - src/validator/mod.rs | 39 +++++++++++++---------- src/validator/predefined.rs | 4 +-- std/lib/beaker.mcl | 40 ++++++++++++------------ test2 | Bin 0 -> 15864 bytes test2.mcl | 16 ++++++++-- 17 files changed, 208 insertions(+), 68 deletions(-) create mode 100755 libbeaker.so create mode 100755 test2 diff --git a/libbeaker.so b/libbeaker.so new file mode 100755 index 0000000000000000000000000000000000000000..dfafb6079939f05936b7833a215d583d5cf1e83f GIT binary patch literal 47688 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 literal 0 HcmV?d00001 diff --git a/src/cli.rs b/src/cli.rs index 382b955..be73892 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -22,6 +22,10 @@ pub struct CliArgs { /// Linker args #[arg(long, short='L')] pub linker_args: Vec, + + /// Link with C libs, required for any C libraries + #[arg(long, short='C')] + pub link_c: bool, /// All input files #[clap(num_args = 1..)] diff --git a/src/common/loc.rs b/src/common/loc.rs index 0b15bce..f5c88d7 100644 --- a/src/common/loc.rs +++ b/src/common/loc.rs @@ -1,6 +1,6 @@ use std::fmt::{Debug, Display}; -#[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)] +#[derive(Debug, Clone, PartialOrd, Ord, Eq, Hash)] pub struct Loc { file: String, line: usize, @@ -64,6 +64,12 @@ impl Default for Loc { } } +impl PartialEq for Loc { + fn eq(&self, _: &Self) -> bool { + true // ignore eq cause comparing 2 locations is irrelevant + } +} + pub trait LocIncr { fn inc_line(&mut self); fn inc_col(&mut self); diff --git a/src/parser/ast/literal.rs b/src/parser/ast/literal.rs index 4daaf1d..9d279dd 100644 --- a/src/parser/ast/literal.rs +++ b/src/parser/ast/literal.rs @@ -1,5 +1,5 @@ -use crate::{common::{Loc, loc::LocBox}, parser::ast::{Program, typ::Type}, tokeniser::tokentype::*, validator::{predefined::SIZE, validate_expr}}; +use crate::{common::{Loc, loc::LocBox}, debug, parser::ast::{Program, typ::Type}, tokeniser::tokentype::*, validator::{predefined::SIZE, validate_expr}}; use super::expr::Expr; @@ -26,7 +26,10 @@ impl Literal { let t = match self { Self::Number(_) => Type::Builtin { name: String::from("usize"), size: SIZE as u8, signed: false }, Self::Ident(ident) => Type::Owned(ident.clone()), - Self::String(str) if str.cstr => Type::Ref { inner: Box::new(Type::Owned(Ident(String::from("cstr")))), mutable: false}, + Self::String(str) if str.cstr => { + debug!("is cstr"); + Type::Ref { inner: Box::new(Type::Owned(Ident(String::from("cstr")))), mutable: false} + }, Self::String(str) if !str.cstr => Type::Ref { inner: Box::new(Type::Owned(Ident(String::from("str")))), mutable: false}, Self::String(_) => unreachable!("stupid rust"), Self::Char(_) => Type::Owned(Ident(String::from("char"))), diff --git a/src/parser/ast/statement.rs b/src/parser/ast/statement.rs index c2ee1fa..9969c2e 100644 --- a/src/parser/ast/statement.rs +++ b/src/parser/ast/statement.rs @@ -60,17 +60,32 @@ pub struct Enum { pub fields: Vec, } -#[derive(Debug, Clone, PartialEq, PartialOrd, Hash)] +#[derive(Debug, Clone, PartialOrd, Hash)] pub struct Function { pub struct_name: Option, - pub name: Ident, + pub name: Option, pub params: Vec<(Ident, LocBox)>, - pub ret_type: Option>, + pub ret_type: Option>>, pub qual_const: bool, pub qual_extern: Option, // abi pub body: Option, // If None then its a type declaration } +impl PartialEq for Function { + fn eq(&self, other: &Self) -> bool { + dbg!(self.params == other.params); + dbg!(self.ret_type == other.ret_type); + dbg!(self.qual_extern == other.qual_extern); + dbg!(self.qual_const == other.qual_const); + dbg!(&self.params); + dbg!(&self.ret_type); + self.params == other.params && + self.ret_type == other.ret_type && + self.qual_extern == other.qual_extern && + self.qual_const == other.qual_const + } +} + impl Display for Function { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut extrn = String::new(); @@ -99,17 +114,25 @@ impl Display for Function { impl Function { pub fn get_full_name(&self) -> String { - if let Some(sn) = &self.struct_name { - format!("{sn}__S__{}", self.name.0) + if let Some(name) = &self.name { + if let Some(sn) = &self.struct_name { + format!("{sn}__S__{}", name.0) + } else { + format!("{}", name.0) + } } else { - format!("{}", self.name.0) + String::new() } } pub fn get_full_name_pretty(&self) -> String { - if let Some(sn) = &self.struct_name { - format!("{sn}::{}", self.name.0) + if let Some(name) = &self.name { + if let Some(sn) = &self.struct_name { + format!("{sn}::{}", name.0) + } else { + format!("{}", name.0) + } } else { - format!("{}", self.name.0) + String::new() } } pub fn get_def_as_str(&self) -> String { diff --git a/src/parser/ast/typ.rs b/src/parser/ast/typ.rs index 2633b48..435c19e 100644 --- a/src/parser/ast/typ.rs +++ b/src/parser/ast/typ.rs @@ -2,7 +2,7 @@ use std::{clone, collections::HashSet, fmt::Display}; use anyhow::bail; -use crate::{common::loc::LocBox, error, info, validator::predefined::{BuiltinType, get_builtin_from_name}}; +use crate::{common::loc::LocBox, error, info, parser::ast::statement::Function, validator::predefined::{BuiltinType, get_builtin_from_name}}; use super::{expr::Expr, literal::Literal, Ident, Program}; @@ -24,7 +24,8 @@ pub enum Type { name: String, size: u8, signed: bool, - } + }, + FnPtr(Function) } impl Type { @@ -67,6 +68,7 @@ impl Type { _ => true, } }, + Self::FnPtr(_) | Self::Owned(_) | Self::SizedArray { .. } | Self::Builtin { .. } | @@ -100,6 +102,7 @@ impl Type { Type::UnsizedArray { inner } => { f(inner, program, used_types) } + Type::FnPtr(_) | Type::Builtin { .. } => Ok(slf.clone()), } } @@ -129,6 +132,7 @@ impl Type { bail!("owo? missing value: {ident}"); } } + Self::FnPtr(_) | Self::SizedArray { .. } | Self::Builtin { .. } | Self::UnsizedArray { .. } => Ok(self.clone()), @@ -155,6 +159,7 @@ impl Type { Self::Ref { inner, .. } | Self::SizedArray { inner, .. } | Self::UnsizedArray { inner, .. } => inner.convert_owned_to_real_type(program), + Self::FnPtr(_) | Self::Builtin { .. } => (), } } @@ -174,6 +179,9 @@ impl Type { } else if let Some(var) = program.get_var(ident) { Ok(var.1.inner().typ.clone().expect("type should be computed if were already using it").inner().clone()) + } else + if let Some(func) = program.functions.get(ident) { + Ok(Type::FnPtr(func.inner().clone())) } else { bail!("owo? missing value: {ident}"); } @@ -181,6 +189,7 @@ impl Type { Self::Ref { .. } | Self::SizedArray { .. } | Self::Builtin { .. } | + Self::FnPtr(_) | Self::UnsizedArray { .. } => Ok(self.clone()), } @@ -197,6 +206,7 @@ impl Type { } }, Self::SizedArray { .. } => false, + Self::FnPtr(_) | Self::UnsizedArray { .. } => false, Self::Builtin { name, .. } => { match name.as_str() { @@ -225,6 +235,7 @@ impl Type { _ => None } }, + Self::FnPtr(_) | Self::SizedArray { .. } => None, Self::UnsizedArray { .. } => None, Self::Builtin { name, .. } => { @@ -273,6 +284,7 @@ impl Type { pub fn size_of(&self, program: &Program) -> anyhow::Result { fn f(t: &Type, program: &Program, behind_a_ptr: bool) -> anyhow::Result { match t { + Type::FnPtr(_) | Type::Ref { .. } => { // TODO: Use the actual ptr size Ok(size_of::<*const ()>()) @@ -323,6 +335,9 @@ impl Type { impl Display for Type { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + Self::FnPtr(func) => { + write!(f, "{func}") + } Self::Ref { inner, mutable } => { if *mutable { write!(f, "&mut {inner}") diff --git a/src/parser/expr.rs b/src/parser/expr.rs index 360e75f..50c9dd1 100644 --- a/src/parser/expr.rs +++ b/src/parser/expr.rs @@ -31,6 +31,7 @@ const BINOP_LIST: &[TokenType] = &[ TokenType::Punct(Punctuation::XorEq), TokenType::Punct(Punctuation::Eq), TokenType::Punct(Punctuation::EqEq), + TokenType::Punct(Punctuation::Neq), TokenType::Punct(Punctuation::Lt), TokenType::Punct(Punctuation::Gt), TokenType::Punct(Punctuation::Le), @@ -45,6 +46,7 @@ pub fn parse_expr(tokens: &mut Vec, precedence: usize, consume_semi: bool Some(LocBox::new(kw.loc(), Expr::Self_ { strct: None })) } else if let Some(_) = utils::check(tokens, TokenType::ident("")) { + debug!("is ident"); let p = parse_path(tokens)?; if let Some(_) = utils::check(tokens, TokenType::Delim(Delimiter::CurlyL)) { Some(parse_struct_literal(tokens, p.inner().unwrap_path(), cli, prog)?) @@ -481,7 +483,7 @@ fn parse_binop(tokens: &mut Vec, mut lhs: LocBox, precedence: usize loop { let op_loc; - let op = match tokens.last() { + let mut op = match tokens.last() { Some(op) if BINOP_LIST.contains(&op.tt()) => { op_loc = op.loc().clone(); let TokenType::Punct(op) = op.tt() else {unreachable!()}; @@ -500,13 +502,28 @@ fn parse_binop(tokens: &mut Vec, mut lhs: LocBox, precedence: usize Some(_) | None => break, }; + + _ = tokens.pop(); + + // Fix for parsing multiple refs in types and references being parsed as && (logical and) + if op == Punctuation::Ampersand { + if let Some(tok) = tokens.last() { + match tok.tt() { + TokenType::Punct(Punctuation::Ampersand) => { + _ = tokens.pop(); + op = Punctuation::AndAnd; + } + _ => () + } + } + } + debug!("OP: {op:?}"); let (lp, rp) = op.precedence().unwrap(); if lp < precedence { break } - _ = tokens.pop(); let Some(rhs) = parse_expr(tokens, rp, false, cli, prog)? else {break;}; lhs = LocBox::new(&op_loc, Expr::BinOp { typ: op, diff --git a/src/parser/stat.rs b/src/parser/stat.rs index 9aca6a5..d5c8147 100644 --- a/src/parser/stat.rs +++ b/src/parser/stat.rs @@ -17,7 +17,7 @@ use super::ast::statement::{ConstVar, Enum, Function, Statement, StaticVar, Stru type Result = anyhow::Result; pub fn parse_statement(tokens: &mut Vec, cli: &CliArgs, prog: &mut Program) -> Result>> { - if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::Fn)) { + if let Some(_) = utils::check_from_many(tokens, &[TokenType::Keyword(Keyword::Fn), TokenType::Keyword(Keyword::Extern)]) { Ok(Some(parse_fn(tokens, cli, prog)?)) } else if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::Type)) { @@ -192,6 +192,17 @@ pub fn parse_type_alias(tokens: &mut Vec) -> Result> { pub fn parse_fn(tokens: &mut Vec, cli: &CliArgs, prog: &mut Program) -> Result> { error!("fnc"); + let mut qual_extern = None; + if let Some(_) = utils::check_consume(tokens, TokenType::Keyword(Keyword::Extern)) { + if let Some(tok) = utils::check_consume(tokens, TokenType::string("", false)) { + if let TokenType::String(str) = tok.tt() { + qual_extern = Some(str.clone()); + } + } else { + qual_extern = Some(TString::default()); + } + } + // Just remove the kw since we checked it before let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Fn), "")?; let mut struct_name = None; @@ -206,7 +217,7 @@ pub fn parse_fn(tokens: &mut Vec, cli: &CliArgs, prog: &mut Program) -> R // Check for return type cause it optional let mut ret_type = None; if let Some(_) = utils::check_consume(tokens, TokenType::Punct(Punctuation::Arrow)) { - ret_type = Some(parse_type(tokens)?); + ret_type = Some(Box::new(parse_type(tokens)?)); } let body; if let Some(_) = utils::check(tokens, TokenType::Delim(Delimiter::CurlyL)) { @@ -228,11 +239,11 @@ pub fn parse_fn(tokens: &mut Vec, cli: &CliArgs, prog: &mut Program) -> R params.append(&mut params_partial.1); Ok(LocBox::new(kw.loc(), Statement::Fn(Function{ struct_name, - name, + name: Some(name), params, ret_type, qual_const: false, - qual_extern: None, + qual_extern, body, }))) } diff --git a/src/parser/typ.rs b/src/parser/typ.rs index bcf50e0..f50e3e5 100644 --- a/src/parser/typ.rs +++ b/src/parser/typ.rs @@ -1,6 +1,6 @@ use anyhow::{Result, bail}; -use crate::{cli::CliArgs, common::loc::LocBox, lerror, parser::{Delimiter, ast::{Ident, Program, expr::Expr, literal::Literal}}, tokeniser::Token, validator::predefined::get_builtin_from_name}; +use crate::{cli::CliArgs, common::loc::LocBox, lerror, parser::{Delimiter, ast::{Ident, Program, expr::Expr, literal::Literal, statement::{Function, Statement}}, stat::parse_fn_params}, tokeniser::Token, validator::predefined::get_builtin_from_name}; use super::{ast::{typ::Type, TokenType}, expr::parse_expr, utils, Keyword, Punctuation}; @@ -19,6 +19,11 @@ pub fn parse_type(tokens: &mut Vec) -> Result> { } let mut typ; + if let Some(_) = utils::check(tokens, TokenType::Keyword(Keyword::Fn)) { + let decl = parse_fn(tokens)?; + loc = Some(decl.loc().clone()); + typ = Type::FnPtr(decl.inner().clone()); + } else if let Some(start) = utils::check_consume(tokens, TokenType::Delim(super::Delimiter::SquareL)) { if let None = loc { loc = Some(start.loc().clone()); @@ -75,3 +80,32 @@ pub fn parse_type(tokens: &mut Vec) -> Result> { } Ok(LocBox::new(&loc.unwrap(), typ)) } + +pub fn parse_fn(tokens: &mut Vec) -> Result> { + let kw = utils::check_consume_or_err(tokens, TokenType::Keyword(Keyword::Fn), "")?; + +// disable member functions for types (for now) +// let mut struct_name = None; +// let mut name = utils::check_consume_or_err(tokens, TokenType::ident(""), "")?.tt().unwrap_ident(); + // Check if this is a struct method +// if let Some(_) = utils::check_consume(tokens, TokenType::Punct(Punctuation::Fieldaccess)) { +// struct_name = Some(name); +// name = utils::check_consume_or_err(tokens, TokenType::ident(""), "")?.tt().unwrap_ident(); +// } + let params = parse_fn_params(tokens)?; + + // Check for return type cause it optional + let mut ret_type = None; + if let Some(_) = utils::check_consume(tokens, TokenType::Punct(Punctuation::Arrow)) { + ret_type = Some(Box::new(parse_type(tokens)?)); + } + Ok(LocBox::new(kw.loc(),Function{ + struct_name: None, + name: None, + params: params.1, + ret_type, + qual_const: false, + qual_extern: None, + body: None, + })) +} diff --git a/src/targets/mod.rs b/src/targets/mod.rs index 2de5425..b2bc42f 100644 --- a/src/targets/mod.rs +++ b/src/targets/mod.rs @@ -56,7 +56,10 @@ pub fn compile(cli: &CliArgs, programs: Vec<(PathBuf, Program)>) -> anyhow::Resu objs.push(obj_p); } let out = Path::new(&cli.output); - target.link(objs, &out, &cli.linker_args)?; + + let mut args = Vec::new(); + args.append(&mut cli.linker_args.clone()); + target.link(objs, &out, &args)?; Ok(()) } diff --git a/src/targets/x86_64/asmgen/linux/mod.rs b/src/targets/x86_64/asmgen/linux/mod.rs index 4c3a1d9..1156748 100644 --- a/src/targets/x86_64/asmgen/linux/mod.rs +++ b/src/targets/x86_64/asmgen/linux/mod.rs @@ -165,12 +165,15 @@ impl FunctionCtx { impl AsmGen { pub fn write_func(&self, program: &Program, f: &mut File, func: Function, loc: Loc) -> anyhow::Result<()> { - if let Some(body) = &func.body { + if func.qual_extern.is_some() { + return Ok(()); + } + if let Some(body) = &func.body && let Some(name) = &func.name { let mut fc = FunctionCtx::new(); let name = if let Some(struct_name) = &func.struct_name { - format!("{}${}", struct_name, func.name) + format!("{}${}", struct_name, name) } else { - func.name.to_string() + name.to_string() }; info!("writing norm function: {name}"); writeln!(f, "{}: ; {} {}", name, loc, func.get_full_name_pretty())?; @@ -217,8 +220,8 @@ impl AsmGen { writeln!(f, " ret")?; } } - } else { - info!("writing function stub: {}", func.name); + } else if let Some(_) = &func.name { + info!("writing function stub: {}", func.get_full_name_pretty()); writeln!(f, " ret")?; } writeln!(f, "\n")?; @@ -601,6 +604,7 @@ impl AsmGen { writeln!(f, "mov [rbx+{offset}], rax")?; }, Punctuation::EqEq => {}, + Punctuation::Neq => {}, Punctuation::Lt => {}, Punctuation::Gt => {}, Punctuation::Le => {}, @@ -624,6 +628,8 @@ impl AsmGen { } } else if let Some(_) = program.get_const_var(&ident) { writeln!(f, " lea rax, [rel {ident}] ; const {ident}")?; + } else if let Some(_) = program.functions.get(&ident) { + writeln!(f, " lea rax, [rel {ident}] ; fn ptr {ident}")?; } else { panic!() } diff --git a/src/tokeniser/mod.rs b/src/tokeniser/mod.rs index 5d799cd..5050af9 100644 --- a/src/tokeniser/mod.rs +++ b/src/tokeniser/mod.rs @@ -282,7 +282,6 @@ lazy_static::lazy_static!( ("%", TokenType::Punct(Punctuation::Mod)), ("<<", TokenType::Punct(Punctuation::Shl)), (">>", TokenType::Punct(Punctuation::Shr)), - ("&&", TokenType::Punct(Punctuation::AndAnd)), ("||", TokenType::Punct(Punctuation::OrOr)), ("|", TokenType::Punct(Punctuation::Or)), (">", TokenType::Punct(Punctuation::Gt)), diff --git a/src/validator/mod.rs b/src/validator/mod.rs index cf7f6f5..1b33b44 100644 --- a/src/validator/mod.rs +++ b/src/validator/mod.rs @@ -423,6 +423,7 @@ pub fn validate_expr(prog: &mut Program, expr: &mut LocBox) -> anyhow::Res *signed = var_t.is_signed(prog).expect("verified as numeric"); Ok(None) } + Punctuation::Neq | Punctuation::Eq => { let var = validate_expr(prog, left)?.unwrap(); let var_t = var.get_absolute_value(prog)?; @@ -435,7 +436,7 @@ pub fn validate_expr(prog: &mut Program, expr: &mut LocBox) -> anyhow::Res Ok(None) } - _ => unreachable!() + v => unreachable!("{v:?}") } }, Expr::ArrayIndex { name, index } => { @@ -473,6 +474,7 @@ pub fn validate_expr(prog: &mut Program, expr: &mut LocBox) -> anyhow::Res } } Type::Ref { .. } | + Type::FnPtr(_) | Type::Builtin { .. } => { lerror!(loc, "Numeric, pointer, and void types are not indexable (TODO: Maybe allow indexing pointers?)"); bail!("") @@ -489,6 +491,7 @@ pub fn validate_expr(prog: &mut Program, expr: &mut LocBox) -> anyhow::Res }; let mut left = left.unwrap(); left.convert_owned_to_real_type(prog); + dbg!(&prog.curr_fn_args); *l_typ = Some(Box::new(left.clone())); match left { Type::Ref { inner, mutable: _ } => { @@ -510,7 +513,7 @@ pub fn validate_expr(prog: &mut Program, expr: &mut LocBox) -> anyhow::Res v => panic!("{v:?}"), } } - v => panic!("{v:?}"), + v => panic!("{} {v:?}", expr.loc()), } Ok(None) @@ -564,9 +567,10 @@ pub fn validate_expr(prog: &mut Program, expr: &mut LocBox) -> anyhow::Res fn validate_fn(prog: &mut Program, func: &mut Function) -> anyhow::Result<()> { prog.scope = Some(Scope::default()); prog.curr_struct = func.struct_name.clone(); - + dbg!(&func.params); for param in &func.params { let t = validate_type(prog, ¶m.1)?; + dbg!(&t); prog.curr_fn_args.insert(param.0.clone(), LocBox::new(&Loc::default(), t.clone())); } if let Some(body) = &mut func.body { @@ -620,16 +624,16 @@ fn check_that_types_exist_for_items(prog: &mut Program, items: &Vec) -> any for (name, t) in &func.params { if let Err(_) = validate_type(prog, t) { if let Some(sn) = &func.struct_name { - lerror!(t.loc(), "Type '{}', of argument, '{name}' in function '{}::{}' does not exist", t.inner(), sn, func.name); + lerror!(t.loc(), "Type '{}', of argument, '{name}' in function '{}::{}' does not exist", t.inner(), sn, func.get_full_name_pretty()); } else { - lerror!(t.loc(), "Type '{}', of argument, '{name}' in function '{}' does not exist", t.inner(), func.name); + lerror!(t.loc(), "Type '{}', of argument, '{name}' in function '{}' does not exist", t.inner(), func.get_full_name_pretty()); } errored = true; } } if let Some(ret_typ) = &func.ret_type { if let Err(_) = validate_type(prog, &ret_typ) { - lerror!(ret_typ.loc(), "Return type '{}' of function '{}' does not exist", ret_typ.inner(), func.name); + lerror!(ret_typ.loc(), "Return type '{}' of function '{}' does not exist", ret_typ.inner(), func.get_full_name_pretty()); errored = true; } } @@ -674,6 +678,7 @@ pub fn validate_type(prog: &mut Program, typ: &LocBox) -> anyhow::Result Ok(typ.clone()), Type::Owned(ident) => { if let Some(builtin) = get_builtin_from_name(&ident.0) { @@ -691,7 +696,7 @@ pub fn validate_type(prog: &mut Program, typ: &LocBox) -> anyhow::Result Ok(typ.clone()) } } - f(prog, &typ.inner().get_real_value_of_alias(&Ident::new(""), prog)?, typ.loc()) + f(prog, &typ.inner(), typ.loc()) } @@ -703,16 +708,18 @@ fn collect_types_and_constants(prog: &mut Program, items: &mut Vec) { let loc = stat.loc().clone(); match stat.inner_mut() { Statement::Fn(func)=> { - if let Some(struct_name) = &func.struct_name { - if let Some(v) = prog.member_functions.get_mut(&struct_name) { - v.insert(func.name.clone(), LocBox::new(&loc, func.clone())); - } else { - let mut v = HashMap::new(); - v.insert(func.name.clone(), LocBox::new(&loc, func.clone())); - prog.member_functions.insert(struct_name.clone(), v); + if let Some(name) = &func.name { + if let Some(struct_name) = &func.struct_name { + if let Some(v) = prog.member_functions.get_mut(&struct_name) { + v.insert(name.clone(), LocBox::new(&loc, func.clone())); + } else { + let mut v = HashMap::new(); + v.insert(name.clone(), LocBox::new(&loc, func.clone())); + prog.member_functions.insert(struct_name.clone(), v); + } + } else { + prog.functions.insert(name.clone(), LocBox::new(&loc, func.clone())); } - } else { - prog.functions.insert(func.name.clone(), LocBox::new(&loc, func.clone())); } } Statement::Enum(enm) => { diff --git a/src/validator/predefined.rs b/src/validator/predefined.rs index d5728dc..3daea28 100644 --- a/src/validator/predefined.rs +++ b/src/validator/predefined.rs @@ -143,7 +143,7 @@ pub fn load_builtin(prog: &mut Program) { let mut ret_type = None; if !ret_typ.is_void() { - ret_type = Some(LocBox::new(&Loc::default(), ret_typ.clone())); + ret_type = Some(Box::new(LocBox::new(&Loc::default(), ret_typ.clone()))); } for (name, typ) in args { params.push((Ident(name.to_string()), LocBox::new(&Loc::new("(internal)", 0, 0), typ.clone()))); @@ -151,7 +151,7 @@ pub fn load_builtin(prog: &mut Program) { let f = Function { struct_name: None, - name: Ident(name.to_string()), + name: Some(Ident(name.to_string())), params, ret_type, qual_const: false, diff --git a/std/lib/beaker.mcl b/std/lib/beaker.mcl index 7ccf69b..426a9bf 100644 --- a/std/lib/beaker.mcl +++ b/std/lib/beaker.mcl @@ -1,4 +1,4 @@ - +include "std/core.mcl"; const MAX_CONTEXT_VARS: usize = 32; const MAX_KEY_LEN: usize = 64; @@ -23,73 +23,73 @@ enum ContextType { type ContextType = i32; struct CV_array_data { values: &&char, - count: i32, + count: i32 } struct CV_2d_array_data { values: &&&char, - count: i32, + count: i32 } struct ContextVarStr { - key: char[MAX_KEY_LEN], + key: [char; MAX_KEY_LEN], typ: ContextType, - value: char[MAX_VALUE_LEN] + value: [char; MAX_VALUE_LEN] } struct ContextVarArr { - key: char[MAX_KEY_LEN], + key: [char; MAX_KEY_LEN], typ: ContextType, value: CV_array_data, } struct ContextVar2dArr { - key: char[MAX_KEY_LEN], + key: [char; MAX_KEY_LEN], typ: ContextType, value: CV_2d_array_data, } struct ContextVar { - key: char[MAX_KEY_LEN], + key: [char; MAX_KEY_LEN], typ: ContextType, - value: char[MAX_VALUE_LEN] + value: [char; MAX_VALUE_LEN] } struct TemplateContext { - vars: ContextVar[MAX_CONTEXT_VARS], + vars: [ContextVar; MAX_CONTEXT_VARS], count: i32, } struct UrlParam { - key: char[MAX_KEY_LEN], - value: char[MAX_VALUE_LEN], + key: [char; MAX_KEY_LEN], + value: [char; MAX_VALUE_LEN], } struct UrlParams { - params: UrlParam[MAX_URL_PARAMS], + params: [UrlParam; MAX_URL_PARAMS], count: i32 } struct Cookie { - name: char[MAX_KEY_LEN], - value: char[MAX_VALUE_LEN], - expires: char[MAX_VALUE_LEN], - path: char[MAX_KEY_LEN], + name: [char; MAX_KEY_LEN], + value: [char; MAX_VALUE_LEN], + expires: [char; MAX_VALUE_LEN], + path: [char; MAX_KEY_LEN], http_only: bool, secure: bool } -type RequestHandler = fn(params: &UrlParams); +type RequestHandler = fn(params: &UrlParams) -> i32; struct RouteHandler { - path: char[MAX_PATH_LEN], + path: [char; MAX_PATH_LEN], handler: RequestHandler } extern fn new_context() -> TemplateContext; extern fn context_set(ctx: &mut TemplateContext, key: &cstr, value: &cstr); extern fn context_set_string_array(ctx: &mut TemplateContext, key: &cstr, values: &cstr, count: i32); -extern fn context_set_array_of_arrays(ctx: &mut TemplateContext, key: &cstr, values: &cstr[][], outer_count: i32, inner_count: i32); +extern fn context_set_array_of_arrays(ctx: &mut TemplateContext, key: &cstr, values: [[&cstr]], outer_count: i32, inner_count: i32); extern fn free_context(ctx: &mut TemplateContext); extern fn render_template(template_file: &cstr, ctx: &mut TemplateContext) -> &cstr; diff --git a/test2 b/test2 new file mode 100755 index 0000000000000000000000000000000000000000..664beccc062ab17fedd33fb971fac612ee237b95 GIT binary patch literal 15864 zcmeHOZD?E989q_0%ym+%x*he{)@sZp`_ag{`mz+dapgqr)gpgHc2cLIT+8-NEGA2y zbdx6QkGXgms3tJRpeqcPF=*MwC}l9l*oK>g%(NZr*avJ-78nHuwjW`vHG|cA-*eyh z`uapJWw3wen0ue|KIeVU$8)Z(j_^5OEtJMW`}PS=A@K!))|(MiQr=yNt*kVO%ZmGi zDIO9JiUYv(z-7u3L@&p!WIa#5>n>v4M@=k48RAgSz502L+G8YB4A-jjnbdG?@kp&&zi{curEKO%CKYQn zVhPy=oCegJ=Zc0a%kYNvpbsKnkp0LB`#;dd`|ut-wh`^(kIz@PdW3DCUvAXxmRo7M zwk=wYYcEymi#4Yy=AFuyoTlBpPzSocXg8hKN~7L#1Zd)wfevUapdK07>g{1uBF+&# zqS6*|kN+50*hfyi0Y0c*B*3$_9HUVypcT*xXa%$aS^=$qRzNGD70?QNm;(Rof8^iR z+TVMv_3-Z=6~el*;fA)~w$^U;-jHG2={JDhe(Wu{_djYv4(%l@yK{RR(qq@r#-A>C z-j?>y(Z-)FcQ(Mb+FSkM8*sPU@B106{ik5wYQLeFOJ+)&J8CoYYT4$V-pNp?1z< zO(@BZ$J))F8^V7U{MiQ;bmKr5gX&35X7MjgQ^JsKb?zE1!oaRNR89i62)||zt+lb0t*|9#$ zsnr^fN1tjmYm1)|J3Zq`<2LvqG!i4RIQ$u0a4({3kGQ+7mUz!ipO_3PJ_`3@KL*nBPm@>z=9}qvS z@UIeoQQ^JaB7Nc|h4-erPaL4nGuQtInTd$OxXF~nzY!l*_`Ad>6#hTNA658+a?T@S zRN)^c{)-AfM0{D{j}rg1!jBO@uka^{|FXiLC;qa+yTm`Q@K=a$EByC}|E0qJiugAb z{x8J;M&aKh{*MYjAU``1@s7gBh<{h%PZ0kPg~w^>_BlEa{` z?=t^&;0M?U;5YZ+uK^!{zxS2?yn_CrgW{0#9R3*iXrNxs{uVM=&z4fp>$3hn|9lkt z|6-4JH?duI3gGXN55c!X#0;>IjSa&~)=k7(Z~~<`F;gf{UG4#xG3g zjASyG$|mEPcrpdI5yLM_81Y;>nKj@_r;|A&lS}($X=5ajjc1`!C{4w)sYJ>zOJy_A zS|*uHK)vZ)CYjnPGvcXKJeN#^Luv$?9?6YlcLJdms3;BH0H0LcFyJ{ler6&+UOXo3 zCrgu~@Pti{jZGJ3?3w&%sj&OB)9xcqwzF7qE5bfktykem*>y(Bw&zC`GnQf{T@ikPf6 z<~o-kFS`?Smh5xQ%CaNlD$CUcsImd2aEr+h+4tR_xBt=lB*ft>6h6i>WkV*R1pnNk zXYD@Qh1_Ad@O&J{&xTB}gqS7bbJE&5KL>9LnRq??S+L&Q-fnRGYRCiz*ToY2_Sv7~ zy;32LKnB+|9Dgljf`#j53F49mvX3}Uj^}kNuIKl|#qqrU9z+rnueUwx-tm7P3b1b+ z&+FwSisyFJ{xgs3C@dR=3lp!uS1I1|Xz9}rdA0v1fx~h6XD0bQObcI}-(cc?Fo)v{ z#z!eWO7SK;5)uvHC|-IBAQ(SK@pI(xBP$OPm0d+pGG=fS_D*kA4c0>!ib z{(06YN9;z{kJ)9&1kW<^_c@;Q&@jQ-;z@ZCGm*De}w}*j*#QvVOV>AC8 z6a?dW-O!=@IAeZ8vkEcipdNB literal 0 HcmV?d00001 diff --git a/test2.mcl b/test2.mcl index b01f40e..55cdf2b 100644 --- a/test2.mcl +++ b/test2.mcl @@ -1,6 +1,18 @@ // include "std/core.mcl"; -include "beaker.mcl"; +include "std/lib/beaker.mcl"; + + + +fn hello_world_handler(params: &UrlParams) -> i32 { + send_response(c"Hello, World!"); + return 0; +} fn main() -> i32 { - //puts("owo\n"); + set_handler(c"/", hello_world_handler); + let result = beaker_run(c"127.0.0.1", 0xff00000000000000 as i32); + + if (!(result as bool)) { + eputs("[APP] Error: Beaker server failed to start.\n"); + } }