more import preparation
This commit is contained in:
@@ -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,
|
||||||
|
|||||||
@@ -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
146
data/util.lang
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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)?))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -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;
|
||||||
|
|||||||
@@ -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),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user