From 5adca32dd47a9a3fcf51271fdebdafff86cc0c6c Mon Sep 17 00:00:00 2001 From: shadow cat Date: Fri, 25 Apr 2025 13:37:26 -0400 Subject: [PATCH] more import preparation --- data/test.lang | 8 ++ data/test2.lang | 17 ++-- data/util.lang | 146 +++++++++++++++++++++++++++++++ src/ir/lower/program.rs | 6 +- src/ir/upper/assoc.rs | 9 +- src/ir/upper/ty.rs | 5 ++ src/ir/upper/validate.rs | 6 +- src/main.rs | 10 ++- src/parser/v3/lower/block.rs | 2 + src/parser/v3/lower/func.rs | 4 +- src/parser/v3/lower/mod.rs | 2 - src/parser/v3/nodes/statement.rs | 12 ++- src/parser/v3/token/keyword.rs | 2 + 13 files changed, 203 insertions(+), 26 deletions(-) create mode 100644 data/util.lang diff --git a/data/test.lang b/data/test.lang index eb38333..9076dbc 100644 --- a/data/test.lang +++ b/data/test.lang @@ -1,8 +1,16 @@ println("testy"); let x = 3; print_dec(x); +subtest(); start(); +fn subtest() { + fn el() { + println("helo el"); + } + el(); +} + struct Test { a: 64, b: 64, diff --git a/data/test2.lang b/data/test2.lang index 7a68ec1..206dd8e 100644 --- a/data/test2.lang +++ b/data/test2.lang @@ -1,13 +1,6 @@ -fn start() { - let x = asm(out = t0) { - li t0, 40 - }; - exit(x); -} +import util; + +util.println("hello!"); +let x = 39; +util.exit(x); -fn exit(status: 64) { - asm (a0 = status) { - li a7, 93 - ecall - }; -} diff --git a/data/util.lang b/data/util.lang new file mode 100644 index 0000000..87388d6 --- /dev/null +++ b/data/util.lang @@ -0,0 +1,146 @@ +fn exit(status: 64) { + asm (a0 = status) { + li a7, 93 + ecall + }; +} + +fn println(msg: slice<8>) { + print(msg); + print("\n"); +} + +fn print(msg: slice<8>) { + asm (a1 = &msg) { + ld a2, 8, a1 + ld a1, 0, a1 + li a0, 1 + li a7, 64 + ecall + } +} + +fn print_hex(x: 64) { + let i = 64; + loop { + i = sub(i, 4); + let c = and(shr(x, i), 15); + if gt(c, 9) { + c = add(c, 7); + }; + c = add(c, 48); + asm (a1 = &c) { + li a2, 1 + li a0, 1 + li a7, 64 + ecall + }; + if lt(i, 1) { + break; + }; + } +} + +fn print_dec(x: 64) { + let i = 1; + loop { + if gt(i, x) { + if lt(i, 2) { + print("0"); + return; + }; + break; + }; + i = mul(i, 10); + }; + let found = 0; + loop { + i = div(i, 10); + let c = rem(div(x, i), 10); + if and(lt(c, 1), not(found)) { + continue; + }; + found = 1; + if gt(c, 9) { + c = add(c, 7); + }; + c = add(c, 48); + asm (a1 = &c) { + li a2, 1 + li a0, 1 + li a7, 64 + ecall + }; + if lt(i, 2) { + break; + }; + }; + if not(found) { + print("0"); + } +} + +fn add(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + add t0, t0, t1 + } +} + +fn mul(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + mul t0, t0, t1 + } +} + +fn div(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + div t0, t0, t1 + } +} + +fn sub(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + sub t0, t0, t1 + } +} + +fn rem(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + rem t0, t0, t1 + } +} + +fn shr(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + srl t0, t0, t1 + } +} + +fn shl(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + sll t0, t0, t1 + } +} + +fn lt(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + slt t0, t0, t1 + } +} + +fn gt(a: 64, b: 64) -> 64 { + lt(b, a) +} + +fn and(a: 64, b: 64) -> 64 { + asm (t0 = a, t1 = b, out = t0) { + and t0, t0, t1 + } +} + +fn not(a: 64) -> 64 { + asm (t0 = a, out = t0) { + xori t0, t0, 1 + } +} + diff --git a/src/ir/lower/program.rs b/src/ir/lower/program.rs index d01d541..22f7816 100644 --- a/src/ir/lower/program.rs +++ b/src/ir/lower/program.rs @@ -31,7 +31,7 @@ impl LProgram { fbuilder.instrs.push(LInstruction::Ret { src: None }); } let res = fbuilder.finish(f); - ssbuilder.write_fn(sym, res, Some(p.names.name(i).to_string())); + ssbuilder.write_fn(sym, res, Some(p.names.path(i).to_string())); } let sym_space = ssbuilder.finish().expect("we failed the mission"); Ok(Self { sym_space, entry }) @@ -142,7 +142,7 @@ impl<'a> LFunctionBuilder<'a> { let sym = self.data.builder.ro_data( src, &data.content, - Some(self.program.names.name(dest.id).to_string()), + Some(self.program.names.path(dest.id).to_string()), ); self.instrs.push(LInstruction::LoadData { dest: dest.id, @@ -163,7 +163,7 @@ impl<'a> LFunctionBuilder<'a> { let sym = self.data.builder.ro_data( src, &data.content, - Some(self.program.names.name(dest.id).to_string()), + Some(self.program.names.path(dest.id).to_string()), ); self.instrs.push(LInstruction::LoadAddr { dest: dest.id, diff --git a/src/ir/upper/assoc.rs b/src/ir/upper/assoc.rs index 22a407a..8ebdfb4 100644 --- a/src/ir/upper/assoc.rs +++ b/src/ir/upper/assoc.rs @@ -32,9 +32,16 @@ impl NameMap { inv_names: core::array::from_fn(|_| HashMap::new()), } } - pub fn name(&self, id: ID) -> &str { + pub fn path(&self, id: ID) -> &str { &self.names[K::INDEX][id.0] } + pub fn name(&self, id: ID) -> &str { + let mut path = self.path(id); + while let Some(i) = path.find("::") { + path = &path[i + 2..]; + } + path + } pub fn id(&self, name: &str) -> Option> { Some(ID::new(*self.inv_names[K::INDEX].get(name)?)) } diff --git a/src/ir/upper/ty.rs b/src/ir/upper/ty.rs index 258a281..25a020d 100644 --- a/src/ir/upper/ty.rs +++ b/src/ir/upper/ty.rs @@ -36,6 +36,11 @@ impl UProgram { pub fn resolve_types(&mut self) { // I LOVE RUST let mut vars = self.vars.clone(); + // set type of vars referring to functions + for (i, f) in self.iter_fns() { + let vi = self.fn_var.var(i); + vars[vi.0].as_mut().expect("bruh").ty = f.ty(self); + } for (i, f) in self.iter_fns() { let mut redo_iter = Vec::new(); let mut ph_vars = Vec::new(); diff --git a/src/ir/upper/validate.rs b/src/ir/upper/validate.rs index 9be6f43..20e19f1 100644 --- a/src/ir/upper/validate.rs +++ b/src/ir/upper/validate.rs @@ -89,7 +89,11 @@ impl UProgram { let destty = &self.expect(dest.id).ty; let f = self.expect(f.id); let Type::Fn { args: argtys, ret } = &f.ty else { - todo!() + output.err(CompilerMsg { + msg: format!("Type {} is not callable", self.type_name(&f.ty)), + spans: vec![dest.span], + }); + continue; }; output.check_assign(self, ret, destty, dest.span); if args.len() != argtys.len() { diff --git a/src/main.rs b/src/main.rs index e2554fe..fdcf584 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,8 @@ // dawg what #![feature(str_as_str)] +pub const FILE_EXT: &str = "lang"; + use ir::{LProgram, UProgram}; use parser::{PModule, ParseResult, ParserCtx}; use std::{ @@ -52,11 +54,11 @@ fn run_file(file: &str, gdb: bool, asm: bool) { program.resolve_types(); // println!("vars:"); // for (id, def) in program.iter_vars() { - // println!(" {id:?} = {}: {}", program.names.name(id), program.type_name(&def.ty)); + // println!(" {id:?} = {}: {}", program.names.path(id), program.type_name(&def.ty)); + // } + // for (id, f) in program.iter_fns() { + // println!("{}:{id:?} = {:#?}", program.names.path(id), f); // } - for (id, f) in program.iter_fns() { - println!("{}:{id:?} = {:#?}", program.names.name(id), f); - } output = program.validate(); if !output.errs.is_empty() { break 'outer; diff --git a/src/parser/v3/lower/block.rs b/src/parser/v3/lower/block.rs index 11bb8ab..14b6e74 100644 --- a/src/parser/v3/lower/block.rs +++ b/src/parser/v3/lower/block.rs @@ -13,6 +13,7 @@ impl FnLowerable for PBlock { let mut statements = Vec::new(); let mut fn_nodes = Vec::new(); let mut struct_nodes = Vec::new(); + let mut imports = Vec::new(); // first sort statements for s in &self.statements { let Some(s) = s.as_ref() else { @@ -23,6 +24,7 @@ impl FnLowerable for PBlock { PStatementLike::Const(pconst_statement) => match pconst_statement { PConstStatement::Fn(f) => fn_nodes.push(f), PConstStatement::Struct(s) => struct_nodes.push(s), + PConstStatement::Import(i) => imports.push(i), }, } } diff --git a/src/parser/v3/lower/func.rs b/src/parser/v3/lower/func.rs index f6a3c78..1828507 100644 --- a/src/parser/v3/lower/func.rs +++ b/src/parser/v3/lower/func.rs @@ -23,6 +23,8 @@ impl PFunction { Some(id) } pub fn lower(&self, id: FnID, p: &mut UProgram, output: &mut CompilerOutput) { + let name = p.names.name(id).to_string(); + p.push_name(&name); let (args, ret) = if let Some(header) = self.header.as_ref() { ( header @@ -56,7 +58,7 @@ impl PFunction { ret, instructions, }; - p.expect_mut(p.fn_var.var(id)).ty = f.ty(p); + p.pop_name(); p.write(id, f) } } diff --git a/src/parser/v3/lower/mod.rs b/src/parser/v3/lower/mod.rs index a67cc60..f35c996 100644 --- a/src/parser/v3/lower/mod.rs +++ b/src/parser/v3/lower/mod.rs @@ -26,10 +26,8 @@ impl PModule { instructions: fctx.instructions, ret: Type::Unit, }; - let ty = f.ty(p); p.write(id, f); p.pop_name(); - p.expect_mut(p.fn_var.var(id)).ty = ty; } } diff --git a/src/parser/v3/nodes/statement.rs b/src/parser/v3/nodes/statement.rs index 6e42d76..af58b78 100644 --- a/src/parser/v3/nodes/statement.rs +++ b/src/parser/v3/nodes/statement.rs @@ -1,6 +1,6 @@ use super::{ - Keyword, Node, PExpr, PFunction, PStruct, PVarDef, Parsable, ParseResult, ParserCtx, Symbol, - Token, + Keyword, Node, PExpr, PFunction, PIdent, PStruct, PVarDef, Parsable, ParseResult, ParserCtx, + Symbol, Token, }; pub enum PStatement { @@ -12,6 +12,7 @@ pub enum PStatement { pub enum PConstStatement { Fn(Node), Struct(Node), + Import(Node), } pub enum PStatementLike { @@ -47,6 +48,10 @@ impl Parsable for PStatementLike { ctx.next(); ParseResult::Ok(Self::Const(PConstStatement::Struct(ctx.parse()?))) } + Token::Keyword(Keyword::Import) => { + ctx.next(); + ParseResult::Ok(Self::Const(PConstStatement::Import(ctx.parse()?))) + } _ => ctx.parse().map(|n| Self::Statement(PStatement::Expr(n))), } } @@ -81,6 +86,9 @@ impl std::fmt::Debug for PConstStatement { Self::Struct(s) => { s.fmt(f)?; } + Self::Import(s) => { + writeln!(f, "import {:?}", s); + } } Ok(()) } diff --git a/src/parser/v3/token/keyword.rs b/src/parser/v3/token/keyword.rs index c4a8ecb..3a0d4de 100644 --- a/src/parser/v3/token/keyword.rs +++ b/src/parser/v3/token/keyword.rs @@ -12,6 +12,7 @@ pub enum Keyword { Impl, For, Asm, + Import, Funne, } @@ -30,6 +31,7 @@ impl Keyword { "trait" => Self::Trait, "impl" => Self::Impl, "asm" => Self::Asm, + "import" => Self::Import, "funne" => Self::Funne, _ => return None, })