more import preparation

This commit is contained in:
2025-04-25 13:37:26 -04:00
parent 4e7c201690
commit 5adca32dd4
13 changed files with 203 additions and 26 deletions

View File

@@ -1,8 +1,16 @@
println("testy"); println("testy");
let x = 3; let x = 3;
print_dec(x); print_dec(x);
subtest();
start(); start();
fn subtest() {
fn el() {
println("helo el");
}
el();
}
struct Test { struct Test {
a: 64, a: 64,
b: 64, b: 64,

View File

@@ -1,13 +1,6 @@
fn start() { import util;
let x = asm(out = t0) {
li t0, 40 util.println("hello!");
}; let x = 39;
exit(x); util.exit(x);
}
fn exit(status: 64) {
asm (a0 = status) {
li a7, 93
ecall
};
}

146
data/util.lang Normal file
View File

@@ -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
}
}

View File

@@ -31,7 +31,7 @@ impl LProgram {
fbuilder.instrs.push(LInstruction::Ret { src: None }); fbuilder.instrs.push(LInstruction::Ret { src: None });
} }
let res = fbuilder.finish(f); 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"); let sym_space = ssbuilder.finish().expect("we failed the mission");
Ok(Self { sym_space, entry }) Ok(Self { sym_space, entry })
@@ -142,7 +142,7 @@ impl<'a> LFunctionBuilder<'a> {
let sym = self.data.builder.ro_data( let sym = self.data.builder.ro_data(
src, src,
&data.content, &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 { self.instrs.push(LInstruction::LoadData {
dest: dest.id, dest: dest.id,
@@ -163,7 +163,7 @@ impl<'a> LFunctionBuilder<'a> {
let sym = self.data.builder.ro_data( let sym = self.data.builder.ro_data(
src, src,
&data.content, &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 { self.instrs.push(LInstruction::LoadAddr {
dest: dest.id, dest: dest.id,

View File

@@ -32,9 +32,16 @@ impl NameMap {
inv_names: core::array::from_fn(|_| HashMap::new()), inv_names: core::array::from_fn(|_| HashMap::new()),
} }
} }
pub fn name<K: Kind>(&self, id: ID<K>) -> &str { pub fn path<K: Kind>(&self, id: ID<K>) -> &str {
&self.names[K::INDEX][id.0] &self.names[K::INDEX][id.0]
} }
pub fn name<K: Kind>(&self, id: ID<K>) -> &str {
let mut path = self.path(id);
while let Some(i) = path.find("::") {
path = &path[i + 2..];
}
path
}
pub fn id<K: Kind>(&self, name: &str) -> Option<ID<K>> { pub fn id<K: Kind>(&self, name: &str) -> Option<ID<K>> {
Some(ID::new(*self.inv_names[K::INDEX].get(name)?)) Some(ID::new(*self.inv_names[K::INDEX].get(name)?))
} }

View File

@@ -36,6 +36,11 @@ impl UProgram {
pub fn resolve_types(&mut self) { pub fn resolve_types(&mut self) {
// I LOVE RUST // I LOVE RUST
let mut vars = self.vars.clone(); 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() { for (i, f) in self.iter_fns() {
let mut redo_iter = Vec::new(); let mut redo_iter = Vec::new();
let mut ph_vars = Vec::new(); let mut ph_vars = Vec::new();

View File

@@ -89,7 +89,11 @@ impl UProgram {
let destty = &self.expect(dest.id).ty; let destty = &self.expect(dest.id).ty;
let f = self.expect(f.id); let f = self.expect(f.id);
let Type::Fn { args: argtys, ret } = &f.ty else { 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); output.check_assign(self, ret, destty, dest.span);
if args.len() != argtys.len() { if args.len() != argtys.len() {

View File

@@ -5,6 +5,8 @@
// dawg what // dawg what
#![feature(str_as_str)] #![feature(str_as_str)]
pub const FILE_EXT: &str = "lang";
use ir::{LProgram, UProgram}; use ir::{LProgram, UProgram};
use parser::{PModule, ParseResult, ParserCtx}; use parser::{PModule, ParseResult, ParserCtx};
use std::{ use std::{
@@ -52,11 +54,11 @@ fn run_file(file: &str, gdb: bool, asm: bool) {
program.resolve_types(); program.resolve_types();
// println!("vars:"); // println!("vars:");
// for (id, def) in program.iter_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(); output = program.validate();
if !output.errs.is_empty() { if !output.errs.is_empty() {
break 'outer; break 'outer;

View File

@@ -13,6 +13,7 @@ impl FnLowerable for PBlock {
let mut statements = Vec::new(); let mut statements = Vec::new();
let mut fn_nodes = Vec::new(); let mut fn_nodes = Vec::new();
let mut struct_nodes = Vec::new(); let mut struct_nodes = Vec::new();
let mut imports = Vec::new();
// first sort statements // first sort statements
for s in &self.statements { for s in &self.statements {
let Some(s) = s.as_ref() else { let Some(s) = s.as_ref() else {
@@ -23,6 +24,7 @@ impl FnLowerable for PBlock {
PStatementLike::Const(pconst_statement) => match pconst_statement { PStatementLike::Const(pconst_statement) => match pconst_statement {
PConstStatement::Fn(f) => fn_nodes.push(f), PConstStatement::Fn(f) => fn_nodes.push(f),
PConstStatement::Struct(s) => struct_nodes.push(s), PConstStatement::Struct(s) => struct_nodes.push(s),
PConstStatement::Import(i) => imports.push(i),
}, },
} }
} }

View File

@@ -23,6 +23,8 @@ impl PFunction {
Some(id) Some(id)
} }
pub fn lower(&self, id: FnID, p: &mut UProgram, output: &mut CompilerOutput) { 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() { let (args, ret) = if let Some(header) = self.header.as_ref() {
( (
header header
@@ -56,7 +58,7 @@ impl PFunction {
ret, ret,
instructions, instructions,
}; };
p.expect_mut(p.fn_var.var(id)).ty = f.ty(p); p.pop_name();
p.write(id, f) p.write(id, f)
} }
} }

View File

@@ -26,10 +26,8 @@ impl PModule {
instructions: fctx.instructions, instructions: fctx.instructions,
ret: Type::Unit, ret: Type::Unit,
}; };
let ty = f.ty(p);
p.write(id, f); p.write(id, f);
p.pop_name(); p.pop_name();
p.expect_mut(p.fn_var.var(id)).ty = ty;
} }
} }

View File

@@ -1,6 +1,6 @@
use super::{ use super::{
Keyword, Node, PExpr, PFunction, PStruct, PVarDef, Parsable, ParseResult, ParserCtx, Symbol, Keyword, Node, PExpr, PFunction, PIdent, PStruct, PVarDef, Parsable, ParseResult, ParserCtx,
Token, Symbol, Token,
}; };
pub enum PStatement { pub enum PStatement {
@@ -12,6 +12,7 @@ pub enum PStatement {
pub enum PConstStatement { pub enum PConstStatement {
Fn(Node<PFunction>), Fn(Node<PFunction>),
Struct(Node<PStruct>), Struct(Node<PStruct>),
Import(Node<PIdent>),
} }
pub enum PStatementLike { pub enum PStatementLike {
@@ -47,6 +48,10 @@ impl Parsable for PStatementLike {
ctx.next(); ctx.next();
ParseResult::Ok(Self::Const(PConstStatement::Struct(ctx.parse()?))) 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))), _ => ctx.parse().map(|n| Self::Statement(PStatement::Expr(n))),
} }
} }
@@ -81,6 +86,9 @@ impl std::fmt::Debug for PConstStatement {
Self::Struct(s) => { Self::Struct(s) => {
s.fmt(f)?; s.fmt(f)?;
} }
Self::Import(s) => {
writeln!(f, "import {:?}", s);
}
} }
Ok(()) Ok(())
} }

View File

@@ -12,6 +12,7 @@ pub enum Keyword {
Impl, Impl,
For, For,
Asm, Asm,
Import,
Funne, Funne,
} }
@@ -30,6 +31,7 @@ impl Keyword {
"trait" => Self::Trait, "trait" => Self::Trait,
"impl" => Self::Impl, "impl" => Self::Impl,
"asm" => Self::Asm, "asm" => Self::Asm,
"import" => Self::Import,
"funne" => Self::Funne, "funne" => Self::Funne,
_ => return None, _ => return None,
}) })