From e2759e500c23312033fbda7136f6f16be7043768 Mon Sep 17 00:00:00 2001 From: Chris Clark <78776922+coffeebe4code@users.noreply.github.com> Date: Mon, 27 May 2024 15:04:54 -0500 Subject: [PATCH] linter integrated into ir (#19) * linter integrated into ir at its most basic level. --- ast/src/lib.rs | 2 +- ir/Cargo.toml | 2 + ir/src/lib.rs | 146 ++++++++++++++++++++++++++------------------ linter/src/lib.rs | 120 +++++++++++++++++++----------------- objmaker/Cargo.toml | 1 + objmaker/src/lib.rs | 87 +++++++++++++------------- types/src/lib.rs | 82 +++++++++++++------------ 7 files changed, 246 insertions(+), 194 deletions(-) diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 63ce405..5012744 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -682,7 +682,7 @@ impl Expr { #[macro_export] macro_rules! expr { ($val:ident, $($inner:tt)*) => { - Box::new(Expr::$val($val::new($($inner)*))) + Box::new(Expr::$val(ast::$val::new($($inner)*))) }; } diff --git a/ir/Cargo.toml b/ir/Cargo.toml index 7acf137..734fa72 100644 --- a/ir/Cargo.toml +++ b/ir/Cargo.toml @@ -11,5 +11,7 @@ symtable = { path="../symtable" } token = { path="../token" } perror = { path="../perror" } lexer = { path="../lexer" } +linter = { path="../linter" } +types = { path="../types" } cranelift-frontend = "0" cranelift-codegen = "0" diff --git a/ir/src/lib.rs b/ir/src/lib.rs index 4f17890..fc2b840 100644 --- a/ir/src/lib.rs +++ b/ir/src/lib.rs @@ -1,4 +1,3 @@ -use ast::*; use cranelift_codegen::entity::EntityRef; use cranelift_codegen::ir::entities::FuncRef; use cranelift_codegen::ir::function::DisplayFunction; @@ -11,40 +10,40 @@ use cranelift_codegen::verifier::verify_function; use cranelift_frontend::*; use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext}; use perror::*; +use std::rc::Rc; use symtable::*; -use token::*; +use types::*; -pub struct IRSource { +pub struct IRSource<'tt> { package: u32, fname: u32, variables: u32, scope: SymTable, + t_scope: &'tt TypeTable, } -impl IRSource { - pub fn new(package: u32, scope: SymTable) -> Self { +impl<'tt> IRSource<'tt> { + pub fn new(package: u32, scope: SymTable, t_scope: &'tt TypeTable) -> Self { IRSource { package, fname: 0, variables: 0, scope, + t_scope, } } - pub fn handle_decl( + pub fn handle_const_init( &mut self, - op: &InnerDecl, + op: &Initialization, builder: &mut FunctionBuilder, ) -> ResultFir { let result = self.add_var(); builder.declare_var(result, I64); - let temp = self.recurse(&op.expr, builder).unwrap(); + let temp = self.recurse(&op.right, builder).unwrap(); // todo:: optimization: not all paths need declare var if value is only ever read. or something similar, this statement is in the same ballpark, but might not be totally correct let x = builder.use_var(temp); - self.scope.table.insert( - op.identifier.into_symbol().val.slice.to_string(), - temp.as_u32(), - ); + self.scope.table.insert(op.left.clone(), temp.as_u32()); builder.def_var(temp, x); Ok(temp) } @@ -53,19 +52,14 @@ impl IRSource { op: &Invoke, builder: &mut FunctionBuilder, ) -> ResultFir { - let mut args: Vec = vec![]; - if op.args.is_some() { - args = op - .args - .as_ref() - .unwrap() - .iter() - .map(|x| { - let result = self.recurse(&x, builder).unwrap(); - return builder.use_var(result).clone(); - }) - .collect::>(); - } + let args: Vec = op + .args + .iter() + .map(|x| { + let result = self.recurse(&x, builder).unwrap(); + return builder.use_var(result).clone(); + }) + .collect::>(); // todo:: get this correct with funcref. on how to get this from slt? let call = builder.ins().call(FuncRef::from_u32(0), args.as_slice()); let result = self.add_var(); @@ -87,33 +81,59 @@ impl IRSource { .collect(); Ok(*temp.last().unwrap()) } - pub fn handle_ret(&mut self, op: &RetOp, builder: &mut FunctionBuilder) -> ResultFir { - let temp = self.recurse(&op.expr, builder).unwrap(); + pub fn handle_ret_void(&mut self, builder: &mut FunctionBuilder) -> ResultFir { + builder.ins().return_(&[]); + Ok(Variable::from_u32(0)) + } + pub fn handle_ret( + &mut self, + op: &UnaryOp, + builder: &mut FunctionBuilder, + ) -> ResultFir { + let temp = self.recurse(&op.val, builder).unwrap(); let arg = builder.use_var(temp); builder.ins().return_(&[arg]); Ok(temp) } - pub fn handle_sym(&self, op: &Symbol) -> ResultFir { + pub fn handle_sym(&self, op: &SymbolAccess) -> ResultFir { Ok(Variable::from_u32( - *self.scope.table.get(&op.val.slice).unwrap(), + *self.scope.table.get(&op.ident).unwrap(), )) } - pub fn handle_num( + pub fn handle_u64(&mut self, num: u64, builder: &mut FunctionBuilder) -> ResultFir { + let result = self.add_var(); + builder.declare_var(result, I64); + let temp = builder + .ins() + .iconst(I64, i64::from_ne_bytes(num.to_ne_bytes())); + builder.def_var(result, temp); + Ok(result) + } + pub fn handle_i64(&mut self, num: i64, builder: &mut FunctionBuilder) -> ResultFir { + let result = self.add_var(); + builder.declare_var(result, I64); + let temp = builder.ins().iconst(I64, num); + builder.def_var(result, temp); + Ok(result) + } + pub fn handle_minus( &mut self, - num: &Number, + num: &BinaryOp, builder: &mut FunctionBuilder, ) -> ResultFir { let result = self.add_var(); builder.declare_var(result, I64); - let temp = builder - .ins() - .iconst(I64, num.val.slice.parse::().unwrap()); + let left = self.recurse(&num.left, builder).unwrap(); + let right = self.recurse(&num.right, builder).unwrap(); + let arg1 = builder.use_var(left); + let arg2 = builder.use_var(right); + let temp = builder.ins().isub(arg1, arg2); builder.def_var(result, temp); Ok(result) } - pub fn handle_bin( + pub fn handle_plus( &mut self, - num: &BinOp, + num: &BinaryOp, builder: &mut FunctionBuilder, ) -> ResultFir { let result = self.add_var(); @@ -122,37 +142,39 @@ impl IRSource { let right = self.recurse(&num.right, builder).unwrap(); let arg1 = builder.use_var(left); let arg2 = builder.use_var(right); - let temp = match num.op.token { - Token::Plus => builder.ins().iadd(arg1, arg2), - Token::Dash => builder.ins().isub(arg1, arg2), - Token::Asterisk => builder.ins().imul(arg1, arg2), - Token::Slash => builder.ins().udiv(arg1, arg2), - _ => panic!("invalid binary operand"), - }; + let temp = builder.ins().iadd(arg1, arg2); builder.def_var(result, temp); Ok(result) } - pub fn recurse(&mut self, expr: &Expr, builder: &mut FunctionBuilder) -> ResultFir { + pub fn recurse( + &mut self, + expr: &TypeTree, + builder: &mut FunctionBuilder, + ) -> ResultFir { match expr { - Expr::Block(op) => self.handle_block(&op, builder), - Expr::Invoke(op) => self.handle_invoke(&op, builder), - Expr::BinOp(op) => self.handle_bin(&op, builder), - Expr::RetOp(op) => self.handle_ret(&op, builder), - Expr::Number(op) => self.handle_num(&op, builder), - Expr::InnerDecl(op) => self.handle_decl(&op, builder), - Expr::Symbol(op) => self.handle_sym(&op), + TypeTree::Block(op) => self.handle_block(&op, builder), + TypeTree::Invoke(op) => self.handle_invoke(&op, builder), + TypeTree::Plus(op) => self.handle_plus(&op, builder), + TypeTree::Minus(op) => self.handle_minus(&op, builder), + TypeTree::Return(op) => self.handle_ret(&op, builder), + TypeTree::ReturnVoid(_) => self.handle_ret_void(builder), + TypeTree::ConstInit(op) => self.handle_const_init(&op, builder), + TypeTree::SymbolAccess(op) => self.handle_sym(&op), + TypeTree::U64(op) => self.handle_u64(*op, builder), + TypeTree::I64(op) => self.handle_i64(*op, builder), _ => panic!("developer error unexpected expression {:?}", expr), } } - pub fn begin(&mut self, func_def: FuncDecl) -> Function { + pub fn begin(&mut self, func_def: Rc>) -> Function { let mut ctx = FunctionBuilderContext::new(); let mut sig = Signature::new(CallConv::SystemV); let name = UserFuncName::user(self.package, self.fname); + let func_init = func_def.into_func_init(); // todo:: types need to be worked out, params and returns defined - if let Some(val) = func_def.args { - val.iter() - .for_each(|_x| sig.params.push(AbiParam::new(I64))); - } + func_init + .args + .iter() + .for_each(|_x| sig.params.push(AbiParam::new(I64))); sig.returns.push(AbiParam::new(I64)); let mut func = Function::with_name_signature(name, sig); self.fname += 1; @@ -160,7 +182,7 @@ impl IRSource { let root_block = builder.create_block(); builder.append_block_params_for_function_params(root_block); builder.switch_to_block(root_block); - let _result = self.recurse(&func_def.block, &mut builder); + let _result = self.recurse(&func_init.block, &mut builder); builder.seal_block(root_block); builder.finalize(); func @@ -183,7 +205,10 @@ impl IRSource { #[cfg(test)] mod tests { use super::*; + use ast::*; use lexer::*; + use linter::*; + use token::*; #[test] fn it_should_build_ret_5() { let func_def = FuncDecl::new( @@ -237,8 +262,11 @@ mod tests { ), None, ); - let mut fir = IRSource::new(0, SymTable::new()); - let result = fir.begin(func_def); + let mut type_table = TypeTable::new(); + let mut linter = LintSource::new("test", &mut type_table); + let linter_result = linter.check_func_decl(&func_def).unwrap(); + let mut fir = IRSource::new(0, SymTable::new(), &linter.ttbl); + let result = fir.begin(linter_result.0); /* * function u0:0() -> i64 system_v * { diff --git a/linter/src/lib.rs b/linter/src/lib.rs index e9917d3..9b2f992 100644 --- a/linter/src/lib.rs +++ b/linter/src/lib.rs @@ -8,12 +8,12 @@ use symtable::*; use token::Token; use types::*; -type ResultTreeType = Result<(Rc>, Type), usize>; +type ResultTreeType = Result<(Rc>, Ty), usize>; pub struct LintSource<'buf, 'sym> { buffer: &'buf str, idx: usize, - slt: &'sym mut TypeTable, + pub ttbl: &'sym mut TypeTable, pub issues: Vec, } @@ -22,7 +22,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { LintSource { buffer, idx: 0, - slt, + ttbl: slt, issues: vec![], } } @@ -60,6 +60,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { }, Expr::BinOp(bin) => match bin.op.token { Token::Plus => self.check_plus(&bin), + Token::Dash => self.check_minus(&bin), Token::Equality => self.check_equality(&bin), Token::Asterisk => self.check_mul(&bin), _ => panic!( @@ -95,7 +96,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let curried = init.block_curried.clone(); let full = tree!(FuncInit, init); - self.slt.table.insert(slice, (Rc::clone(&full), 0)); + self.ttbl.table.insert(slice, (Rc::clone(&full), 0)); return Ok((full, curried)); } @@ -103,15 +104,15 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let result: Vec = td.exprs.iter().map(|e| self.lint_recurse(&e)).collect(); let mut blk = types::Block { exprs: vec![], - curried: Type::Void, + curried: Ty::Void, }; - let mut typ = Type::Void; + let mut typ = Ty::Void; result.into_iter().for_each(|res| { if let Ok(exp) = res { blk.exprs.push(exp.0); typ = exp.1; } else { - typ = Type::Void; + typ = Ty::Void; } }); @@ -121,7 +122,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { } pub fn check_undefined(&mut self) -> ResultTreeType { - let typ = Type::Undefined; + let typ = Ty::Undefined; ok_simple_tree!(UndefinedValue, typ) } @@ -154,7 +155,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { return; } mat.arms.push(simple_tree!(UnknownValue)); - mat.curried_arms.push(Type::Unknown); + mat.curried_arms.push(Ty::Unknown); }); let cur = mat.curried.clone(); return ok_tree!(Match, mat, cur); @@ -163,7 +164,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { pub fn check_declarator(&mut self, decl: &Declarator) -> ResultTreeType { let dec = DeclaratorInfo { name: decl.ident.into_symbol().val.slice.clone(), - curried: Type::Undefined, + curried: Ty::Undefined, }; let curried = dec.curried.clone(); return ok_tree!(DeclaratorInfo, dec, curried); @@ -172,9 +173,9 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { pub fn check_symbol_ref(&mut self, symbol: &Symbol) -> ResultTreeType { let sym = SymbolAccess { ident: symbol.val.slice.clone(), - curried: Type::Void, + curried: Ty::Void, }; - let typ = Type::Void; + let typ = Ty::Void; return ok_tree!(SymbolAccess, sym, typ); } @@ -182,7 +183,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let mut array = ArrayInitialize { vals: vec![], vals_curried: vec![], - curried: Type::Void, + curried: Ty::Void, }; if let Some(args) = &arr.args { args.into_iter().for_each(|e| { @@ -190,8 +191,8 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { array.vals.push(r.0); } else { array.vals.push(simple_tree!(UnknownValue)); - array.vals_curried.push(Type::Unknown); - array.curried = Type::Unknown; + array.vals_curried.push(Ty::Unknown); + array.curried = Ty::Unknown; } }); } @@ -209,31 +210,29 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let full = tree!(ErrorInfo, err_info); - self.slt.table.insert(slice.clone(), (Rc::clone(&full), 0)); - let curried = Type::ErrorDecl; + self.ttbl.table.insert(slice.clone(), (Rc::clone(&full), 0)); + let curried = Ty::ErrorDecl; return Ok((full, curried)); } pub fn check_self_value(&mut self) -> ResultTreeType { - let self_ref = NoOp { - curried: Type::Void, - }; + let self_ref = NoOp { curried: Ty::Void }; let curried = self_ref.curried.clone(); ok_tree!(SelfRef, self_ref, curried) } pub fn check_chars_value(&mut self, chars: &ast::CharsValue) -> ResultTreeType { let mut vals: Vec>> = vec![]; - let mut vals_curried: Vec = vec![]; + let mut vals_curried: Vec = vec![]; chars.val.slice.chars().for_each(|x| { vals.push(tree!(Char, x)); - vals_curried.push(Type::Char); + vals_curried.push(Ty::Char); }); let chars_result = ArrayInitialize { vals, vals_curried, - curried: Type::String, + curried: Ty::String, }; let curried = chars_result.curried.clone(); ok_tree!(StringInit, chars_result, curried) @@ -259,7 +258,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let mut obj_info = StructInfo { props: vec![], types: vec![], - curried: Type::Custom(slice.clone()), + curried: Ty::Custom(slice.clone()), }; result.into_iter().for_each(|res| { if let Ok(exp) = res { @@ -270,13 +269,13 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { obj_info .props .push(res.unwrap().0.into_declarator().name.clone()); - obj_info.types.push(Type::Unknown); + obj_info.types.push(Ty::Unknown); }); let curried = obj_info.curried.clone(); let full = tree!(StructInfo, obj_info); - self.slt.table.insert(slice, (Rc::clone(&full), 0)); + self.ttbl.table.insert(slice, (Rc::clone(&full), 0)); return Ok((full, curried)); } let mut err = make_error("expected at least one declarator".to_string()); @@ -300,7 +299,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let curried = init.curried.clone(); let full = tree!(PropInit, init); - self.slt.table.insert(slice.clone(), (Rc::clone(&full), 0)); + self.ttbl.table.insert(slice.clone(), (Rc::clone(&full), 0)); return Ok((full, curried)); } @@ -323,14 +322,14 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { .push(x.0.into_prop_init().curried.clone()); } else { struct_init.idents.push("unknown".to_string()); - struct_init.vals_curried.push(Type::Unknown); + struct_init.vals_curried.push(Ty::Unknown); } }); let curried = struct_init.curried.clone(); let full = tree!(StructInit, struct_init); - self.slt.table.insert( + self.ttbl.table.insert( prev.0.into_symbol_access().ident.clone(), (Rc::clone(&full), 0), ); @@ -358,7 +357,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { name: slice, props: vec![], types: vec![], - curried: Type::Custom(copy.clone()), + curried: Ty::Custom(copy.clone()), }; result.into_iter().for_each(|res| { if let Ok(exp) = res { @@ -367,13 +366,13 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { return; } tag_info.props.push(simple_tree!(UnknownValue)); - tag_info.types.push(Type::Unknown); + tag_info.types.push(Ty::Unknown); }); let curried = tag_info.curried.clone(); let full = tree!(TagInfo, tag_info); - self.slt.table.insert(copy, (Rc::clone(&full), 0)); + self.ttbl.table.insert(copy, (Rc::clone(&full), 0)); return Ok((full, curried)); } @@ -392,7 +391,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let curried = init.block_curried.clone(); let full = tree!(AnonFuncInit, init); - self.slt.table.insert(slice, (Rc::clone(&full), 0)); + self.ttbl.table.insert(slice, (Rc::clone(&full), 0)); return Ok((full, curried)); } @@ -407,7 +406,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { }; let curried = init.curried.clone(); let full: Rc> = tree!(ConstInit, init); - self.slt + self.ttbl .table .insert(slice.val.slice, (Rc::clone(&full), 0)); return Ok((full, curried)); @@ -426,7 +425,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let curried = init.curried.clone(); let full = tree!(ConstInit, init); - self.slt.table.insert(copy, (Rc::clone(&full), 0)); + self.ttbl.table.insert(copy, (Rc::clone(&full), 0)); return Ok((full, curried)); } @@ -443,7 +442,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let curried = init.curried.clone(); let full = tree!(ConstInit, init); - self.slt.table.insert(copy, (Rc::clone(&full), 0)); + self.ttbl.table.insert(copy, (Rc::clone(&full), 0)); return Ok((full, curried)); } @@ -454,11 +453,11 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { curried: result.1, }; match unop.val.as_ref().as_ref() { - TypeTree::F64(_) => unop.curried = Type::F64, - TypeTree::U64(_) => unop.curried = Type::I64, - TypeTree::U32(_) => unop.curried = Type::I32, - TypeTree::I64(_) => unop.curried = Type::I64, - TypeTree::I32(_) => unop.curried = Type::I32, + TypeTree::F64(_) => unop.curried = Ty::F64, + TypeTree::U64(_) => unop.curried = Ty::I64, + TypeTree::U32(_) => unop.curried = Ty::I32, + TypeTree::I64(_) => unop.curried = Ty::I64, + TypeTree::I32(_) => unop.curried = Ty::I32, _ => { let mut err = make_error("invalid negation".to_string()); self.update_error( @@ -483,7 +482,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { curried: result.1, }; match unop.val.as_ref().as_ref() { - TypeTree::BoolValue(_) => unop.curried = Type::Bool, + TypeTree::BoolValue(_) => unop.curried = Ty::Bool, _ => panic!("copy checked failed"), } let curried = unop.curried.clone(); @@ -497,7 +496,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { curried: result.1, }; match unop.val.as_ref().as_ref() { - TypeTree::BoolValue(_) => unop.curried = Type::Bool, + TypeTree::BoolValue(_) => unop.curried = Ty::Bool, _ => panic!("clone check failed"), } let curried = unop.curried.clone(); @@ -522,7 +521,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { curried: result.1, }; match unop.val.as_ref().as_ref() { - TypeTree::BoolValue(_) => unop.curried = Type::Bool, + TypeTree::BoolValue(_) => unop.curried = Ty::Bool, _ => panic!("not check failed"), } let curried = unop.curried.clone(); @@ -557,7 +556,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { return; } invoke.args.push(simple_tree!(UnknownValue)); - invoke.args_curried.push(Type::Unknown); + invoke.args_curried.push(Ty::Unknown); }) }; let curried = invoke.curried.clone(); @@ -571,7 +570,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let binop = BinaryOp { left: left.0, right: right.0, - curried: Type::F64, + curried: Ty::F64, }; let curried = binop.curried.clone(); @@ -584,13 +583,26 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { let binop = BinaryOp { left: left.0, right: right.0, - curried: Type::Bool, + curried: Ty::Bool, }; let curried = binop.curried.clone(); ok_tree!(Plus, binop, curried) } + pub fn check_minus(&mut self, bin: &BinOp) -> ResultTreeType { + let left = self.lint_recurse(&bin.left)?; + let right = self.lint_recurse(&bin.right)?; + let binop = BinaryOp { + left: left.0, + right: right.0, + curried: left.1, + }; + let curried = binop.curried.clone(); + + return ok_tree!(Minus, binop, curried); + } + pub fn check_plus(&mut self, bin: &BinOp) -> ResultTreeType { let left = self.lint_recurse(&bin.left)?; let right = self.lint_recurse(&bin.right)?; @@ -605,9 +617,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { } pub fn check_rest(&mut self) -> ResultTreeType { - let restop = NoOp { - curried: Type::Rest, - }; + let restop = NoOp { curried: Ty::Rest }; let curried = restop.curried.clone(); return ok_tree!(RestAccess, restop, curried); @@ -634,9 +644,9 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { }; match unop.val.as_ref().as_ref() { TypeTree::SymbolAccess(sym) => { - unop.curried = Type::MutBorrow(Box::new(sym.curried.clone())) + unop.curried = Ty::MutBorrow(Box::new(sym.curried.clone())) } - TypeTree::SelfRef(sym) => unop.curried = Type::MutBorrow(Box::new(sym.curried.clone())), + TypeTree::SelfRef(sym) => unop.curried = Ty::MutBorrow(Box::new(sym.curried.clone())), _ => panic!("borrow_check failed"), } let curried = unop.curried.clone(); @@ -651,7 +661,7 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { }; match unop.val.as_ref().as_ref() { TypeTree::SymbolAccess(sym) => { - unop.curried = Type::ReadBorrow(Box::new(sym.curried.clone())) + unop.curried = Ty::ReadBorrow(Box::new(sym.curried.clone())) } _ => panic!("borrow_check failed"), } @@ -661,13 +671,13 @@ impl<'buf, 'sym> LintSource<'buf, 'sym> { pub fn check_f64(&mut self, num: &Number) -> ResultTreeType { let val = num.val.slice.parse::().unwrap(); - let typ = Type::F64; + let typ = Ty::F64; return ok_tree!(F64, val, typ); } pub fn check_u64(&mut self, num: &Number) -> ResultTreeType { let val = num.val.slice.parse::().unwrap(); - let typ = Type::U64; + let typ = Ty::U64; return ok_tree!(U64, val, typ); } diff --git a/objmaker/Cargo.toml b/objmaker/Cargo.toml index 0bb2f2d..40502d9 100644 --- a/objmaker/Cargo.toml +++ b/objmaker/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" ast = { path = "../ast" } symtable = { path = "../symtable" } lexer = { path = "../lexer" } +linter = { path = "../linter" } token = { path = "../token" } parser = { path = "../parser" } ir = { path = "../ir" } diff --git a/objmaker/src/lib.rs b/objmaker/src/lib.rs index 9f46aa8..bb8d747 100644 --- a/objmaker/src/lib.rs +++ b/objmaker/src/lib.rs @@ -1,6 +1,6 @@ -use ast::Expr; use ir::IRSource; use lexer::TLexer; +use linter::LintSource; use object::build_std_fn; use object::flush_obj; use object::new_obj_handler; @@ -12,56 +12,61 @@ use std::io::Read; use std::path::Path; use std::path::PathBuf; use symtable::SymTable; +use symtable::TypeTable; pub fn from_buffer(contents: &str, path: &Path) -> () { let lex = TLexer::new(&contents); let mut parse = Parser::new(lex); - let ast_parsed = parse.top_decl().unwrap(); - let mut ir = IRSource::new(0, SymTable::new()); - match *ast_parsed { - Expr::FuncDecl(val) => { - let result = ir.begin(val); - if !Path::new(".ty-cache").is_dir() { - create_dir(".ty-cache").unwrap(); - } - let wo_extension = path.with_extension(""); - let filename = wo_extension.file_name().unwrap().to_str().unwrap(); - let mut output = PathBuf::new(); - output.push(".ty-cache"); - output.push(filename); - output.set_extension("o"); - let mut om = new_obj_handler(filename); - build_std_fn(&mut om, result, filename); - write(output, flush_obj(om)).unwrap(); - } - _ => panic!("not a func def!"), + let ast_parsed = parse.all().unwrap(); + let mut type_table = TypeTable::new(); + let mut linter = LintSource::new(path.to_str().unwrap(), &mut type_table); + let lint_res = linter.lint_check(&ast_parsed); + let mut ir = IRSource::new(0, SymTable::new(), linter.ttbl); + if linter.issues.len() > 0 { + panic!("linter issues exist"); } + let rc_thing = lint_res.first().unwrap().to_owned(); + let result = ir.begin(rc_thing); + if !Path::new(".ty-cache").is_dir() { + create_dir(".ty-cache").unwrap(); + } + let wo_extension = path.with_extension(""); + let filename = wo_extension.file_name().unwrap().to_str().unwrap(); + let mut output = PathBuf::new(); + output.push(".ty-cache"); + output.push(filename); + output.set_extension("o"); + let mut om = new_obj_handler(filename); + build_std_fn(&mut om, result, filename); + write(output, flush_obj(om)).unwrap(); } pub fn from_file(input_path: &PathBuf) -> () { - let mut ty = File::open(input_path.clone()).unwrap(); + let mut file = File::open(input_path.clone()).unwrap(); let mut contents = String::new(); - ty.read_to_string(&mut contents).unwrap(); + file.read_to_string(&mut contents).unwrap(); let lex = TLexer::new(&contents); let mut parse = Parser::new(lex); - let ast_parsed = parse.top_decl().unwrap(); - let mut ir = IRSource::new(0, SymTable::new()); - match *ast_parsed { - Expr::FuncDecl(val) => { - let result = ir.begin(val); - if !Path::new(".ty-cache").is_dir() { - create_dir(".ty-cache").unwrap(); - } - let wo_extension = input_path.with_extension(""); - let filename = wo_extension.file_name().unwrap().to_str().unwrap(); - let mut output = PathBuf::new(); - output.push(".ty-cache"); - output.push(filename); - output.set_extension("o"); - let mut om = new_obj_handler(filename); - build_std_fn(&mut om, result, filename); - write(output, flush_obj(om)).unwrap(); - } - _ => panic!("not a func def!"), + let ast_parsed = parse.all().unwrap(); + let mut type_table = TypeTable::new(); + let mut linter = LintSource::new(input_path.to_str().unwrap(), &mut type_table); + let lint_res = linter.lint_check(&ast_parsed); + let mut ir = IRSource::new(0, SymTable::new(), linter.ttbl); + if linter.issues.len() > 0 { + panic!("linter issues exist"); + } + let rc_thing = lint_res.first().unwrap().to_owned(); + let result = ir.begin(rc_thing); + if !Path::new(".ty-cache").is_dir() { + create_dir(".ty-cache").unwrap(); } + let wo_extension = input_path.with_extension(""); + let filename = wo_extension.file_name().unwrap().to_str().unwrap(); + let mut output = PathBuf::new(); + output.push(".ty-cache"); + output.push(filename); + output.set_extension("o"); + let mut om = new_obj_handler(filename); + build_std_fn(&mut om, result, filename); + write(output, flush_obj(om)).unwrap(); } diff --git a/types/src/lib.rs b/types/src/lib.rs index 0f51010..12ca087 100644 --- a/types/src/lib.rs +++ b/types/src/lib.rs @@ -3,7 +3,7 @@ use std::rc::Rc; #[derive(Debug)] pub struct FileContainer { pub top_items: Vec>>, - pub curried: Vec, + pub curried: Vec, } #[derive(Debug)] @@ -16,132 +16,132 @@ pub struct ErrorInfo { pub struct TagInfo { pub name: String, pub props: Vec>>, - pub types: Vec, - pub curried: Type, + pub types: Vec, + pub curried: Ty, } #[derive(Debug)] pub struct StructInfo { pub props: Vec, - pub types: Vec, - pub curried: Type, + pub types: Vec, + pub curried: Ty, } #[derive(Debug)] pub struct ArgInfo { - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct DeclaratorInfo { pub name: String, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct MatchOp { pub expr: Rc>, - pub curried: Type, + pub curried: Ty, pub arms: Vec>>, - pub curried_arms: Vec, + pub curried_arms: Vec, } #[derive(Debug)] pub struct ForOp { pub in_expr: Rc>, - pub in_curried: Type, + pub in_curried: Ty, pub body: Rc>, - pub body_curried: Type, + pub body_curried: Ty, } #[derive(Debug)] pub struct BinaryOp { pub left: Rc>, pub right: Rc>, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct UnaryOp { pub val: Rc>, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct NoOp { - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct Invoke { pub args: Vec>>, - pub args_curried: Vec, + pub args_curried: Vec, pub ident: Rc>, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct Initialization { pub left: String, pub right: Rc>, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct Reassignment { pub left: Rc>, pub right: Rc>, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct PropAccess { pub prev: Rc>, pub ident: String, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct SymbolAccess { pub ident: String, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct ArrayAccess { pub prev: Rc>, pub inner: Rc>, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] pub struct StructInitialize { pub idents: Vec, pub vals: Vec>>, - pub vals_curried: Vec, - pub curried: Type, + pub vals_curried: Vec, + pub curried: Ty, } #[derive(Debug)] pub struct ArrayInitialize { pub vals: Vec>>, - pub vals_curried: Vec, - pub curried: Type, + pub vals_curried: Vec, + pub curried: Ty, } #[derive(Debug)] pub struct FunctionInitialize { pub name: String, pub args: Vec>>, - pub args_curried: Vec, + pub args_curried: Vec, pub block: Rc>, - pub block_curried: Type, + pub block_curried: Ty, } #[derive(Debug)] pub struct Block { pub exprs: Vec>>, - pub curried: Type, + pub curried: Ty, } #[derive(Debug)] @@ -224,6 +224,12 @@ impl TypeTree { _ => panic!("issue declarator not found"), } } + pub fn into_func_init(&self) -> &FunctionInitialize { + match self { + TypeTree::FuncInit(x) => x, + _ => panic!("issue declarator not found"), + } + } pub fn into_symbol_access(&self) -> &SymbolAccess { match self { TypeTree::SymbolAccess(x) => x, @@ -310,7 +316,7 @@ impl TypeTree { } #[derive(Clone, Debug, PartialEq, Eq)] -pub enum Type { +pub enum Ty { I64, I32, U64, @@ -325,16 +331,16 @@ pub enum Type { Bool, Char, String, - MutBorrow(Box), - ReadBorrow(Box), - Frame(Vec), - Error(Box), - Struct(Vec), - Tag(Vec), - Function(Vec, Box), + MutBorrow(Box), + ReadBorrow(Box), + Frame(Vec), + Error(Box), + Struct(Vec), + Tag(Vec), + Function(Vec, Box), Custom(String), - Array(Box), - Multi(Vec), + Array(Box), + Multi(Vec), } #[macro_export]