diff --git a/src/ast_compiler.rs b/src/ast_compiler.rs index 23dedd2..706ea35 100644 --- a/src/ast_compiler.rs +++ b/src/ast_compiler.rs @@ -16,10 +16,7 @@ use crate::tokens::{Token, TokenType}; use crate::value::Value; use log::debug; use std::collections::HashMap; - -type SymbolTable = HashMap; -type Expr = Result; -type Stmt = Result; +use crate::{Expr, Stmt, SymbolTable}; pub fn compile( path: Option<&str>, diff --git a/src/bytecode_compiler.rs b/src/bytecode_compiler.rs index 639cb6c..6024f88 100644 --- a/src/bytecode_compiler.rs +++ b/src/bytecode_compiler.rs @@ -6,22 +6,28 @@ use crate::symbol_builder::{Symbol, calculate_type, infer_type}; use crate::tokens::TokenType; use crate::tokens::TokenType::Unknown; use crate::value::Value; -use crate::vm::{OP_ADD, OP_AND, OP_ASSIGN, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CALL, OP_CALL_BUILTIN, OP_CONSTANT, OP_DEF_LIST, OP_DEF_MAP, OP_DIVIDE, OP_EQUAL, OP_GET, OP_GREATER, OP_GREATER_EQUAL, OP_LESS, OP_LESS_EQUAL, OP_LIST_GET, OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_OR, OP_PRINT, OP_RETURN, OP_SHL, OP_SHR, OP_SUBTRACT}; +use crate::vm::{ + OP_ADD, OP_AND, OP_ASSIGN, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CALL, OP_CALL_BUILTIN, + OP_CONSTANT, OP_DEF_LIST, OP_DEF_MAP, OP_DIVIDE, OP_EQUAL, OP_GET, OP_GREATER, + OP_GREATER_EQUAL, OP_LESS, OP_LESS_EQUAL, OP_LIST_GET, OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_OR, + OP_PRINT, OP_RETURN, OP_SHL, OP_SHR, OP_SUBTRACT, +}; +use crate::{Registry, SymbolTable}; use std::collections::HashMap; pub fn compile( qualified_name: Option<&str>, ast: &Vec, - symbols: &HashMap, - registry: &mut HashMap, + symbols: &SymbolTable, + registry: &mut Registry, ) -> Result<(), CompilerErrorAtLine> { compile_in_namespace(ast, qualified_name, symbols, registry) } pub(crate) fn compile_function( function: &Function, - symbols: &HashMap, - registry: &mut HashMap, + symbols: &SymbolTable, + registry: &mut Registry, namespace: &str, ) -> Result { let fn_name = &function.name.lexeme; @@ -40,8 +46,8 @@ pub(crate) fn compile_function( pub(crate) fn compile_in_namespace( ast: &Vec, namespace: Option<&str>, - symbols: &HashMap, - registry: &mut HashMap, + symbols: &SymbolTable, + registry: &mut Registry, ) -> Result<(), CompilerErrorAtLine> { let name = namespace.unwrap_or("main"); let compiler = Compiler::new(name); @@ -75,8 +81,8 @@ impl Compiler { fn compile( mut self, ast: &Vec, - symbols: &HashMap, - registry: &mut HashMap, + symbols: &SymbolTable, + registry: &mut Registry, namespace: &str, ) -> Result { for statement in ast { @@ -87,11 +93,15 @@ impl Compiler { Ok(self.chunk) } + fn raise(&self, error: CompilerError) -> CompilerErrorAtLine { + CompilerErrorAtLine::raise(error, self.current_line) + } + fn compile_statement( &mut self, statement: &Statement, - symbols: &HashMap, - registry: &mut HashMap, + symbols: &SymbolTable, + registry: &mut Registry, namespace: &str, ) -> Result<(), CompilerErrorAtLine> { self.current_line = statement.line(); @@ -103,23 +113,20 @@ impl Compiler { let var = symbols.get(name); if let Some(Symbol::Variable { var_type, .. }) = var { let inferred_type = infer_type(initializer, symbols); - let calculated_type = calculate_type(var_type, &inferred_type) - .map_err(|e| CompilerErrorAtLine::raise(e, statement.line()))?; + let calculated_type = + calculate_type(var_type, &inferred_type).map_err(|e| self.raise(e))?; if var_type != &Unknown && var_type != &calculated_type { - return Err(CompilerErrorAtLine::raise( - CompilerError::IncompatibleTypes(var_type.clone(), calculated_type), - statement.line(), - )); + return Err(self.raise(CompilerError::IncompatibleTypes( + var_type.clone(), + calculated_type, + ))); } let name_index = self.chunk.add_var(var_type, name); self.vars.insert(name.to_string(), name_index); self.compile_expression(namespace, initializer, symbols, registry)?; self.emit_bytes(OP_ASSIGN, name_index as u16); } else { - return Err(CompilerErrorAtLine::raise( - CompilerError::UndeclaredVariable(name.to_string()), - statement.line(), - )); + return Err(self.raise(CompilerError::UndeclaredVariable(name.to_string()))); } } Statement::PrintStmt { value } => { @@ -151,8 +158,8 @@ impl Compiler { &mut self, namespace: &str, expression: &Expression, - symbols: &HashMap, - registry: &mut HashMap, + symbols: &SymbolTable, + registry: &mut Registry, ) -> Result<(), CompilerErrorAtLine> { match expression { Expression::FunctionCall { @@ -181,10 +188,7 @@ impl Compiler { self.emit_byte(arguments.len() as u16); } _ => { - return Err(CompilerErrorAtLine::raise( - CompilerError::FunctionNotFound(name.to_string()), - 0, - )); + return Err(self.raise(CompilerError::FunctionNotFound(name.to_string()))); } } } @@ -195,19 +199,19 @@ impl Compiler { .. } => { self.compile_expression(namespace, receiver, symbols, registry)?; - let receiver_type = infer_type(receiver,symbols).to_string(); + let receiver_type = infer_type(receiver, symbols).to_string(); let type_index = self .chunk .find_constant(&receiver_type) .unwrap_or_else(|| self.chunk.add_constant(Value::String(receiver_type))); - let name_index = self - .chunk - .find_constant(&method_name) - .unwrap_or_else(|| self.chunk.add_constant(Value::String(method_name.to_string()))); + let name_index = self.chunk.find_constant(&method_name).unwrap_or_else(|| { + self.chunk + .add_constant(Value::String(method_name.to_string())) + }); //TODO lookup parameters for builtin - self.get_arguments_in_order( namespace, symbols, registry, arguments, &vec![])?; + self.get_arguments_in_order(namespace, symbols, registry, arguments, &vec![])?; self.emit_byte(OP_CALL_BUILTIN); self.emit_byte(name_index as u16); self.emit_byte(type_index as u16); @@ -218,10 +222,7 @@ impl Compiler { if let Some(name_index) = name_index { self.emit_bytes(OP_GET, *name_index as u16); } else { - return Err(CompilerErrorAtLine::raise( - CompilerError::UndeclaredVariable(name.to_string()), - *line, - )); + return Err(self.raise(CompilerError::UndeclaredVariable(name.to_string()))); } } Expression::Literal { value, .. } => { @@ -305,8 +306,8 @@ impl Compiler { fn get_arguments_in_order( &mut self, namespace: &str, - symbols: &HashMap, - registry: &mut HashMap, + symbols: &SymbolTable, + registry: &mut Registry, arguments: &Vec, parameters: &Vec, ) -> Result<(), CompilerErrorAtLine> { @@ -316,13 +317,10 @@ impl Compiler { if name.lexeme == parameter.name.lexeme { let value_type = infer_type(value, symbols); if parameter.var_type != value_type { - return Err(CompilerErrorAtLine::raise( - CompilerError::IncompatibleTypes( - parameter.var_type.clone(), - value_type, - ), - argument.line(), - )); + return Err(self.raise(CompilerError::IncompatibleTypes( + parameter.var_type.clone(), + value_type, + ))); } else { self.compile_expression(namespace, argument, symbols, registry)?; break; diff --git a/src/lib.rs b/src/lib.rs index bf11a8e..442f960 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,9 @@ +use crate::ast_compiler::{Expression, Statement}; use crate::chunk::Chunk; -use crate::errors::CrudLangError; use crate::errors::CrudLangError::Platform; +use crate::errors::{CompilerErrorAtLine, CrudLangError}; use crate::scanner::scan; +use crate::symbol_builder::Symbol; use crate::value::Value; use crate::vm::interpret; use arc_swap::ArcSwap; @@ -11,6 +13,7 @@ use std::sync::Arc; use walkdir::WalkDir; pub mod ast_compiler; +mod builtins; pub mod bytecode_compiler; pub mod chunk; mod compiler_tests; @@ -23,7 +26,11 @@ mod symbol_builder; mod tokens; mod value; pub mod vm; -mod builtins; + +pub(crate) type SymbolTable = HashMap; +pub(crate) type Expr = Result; +pub(crate) type Stmt = Result; +pub(crate) type Registry = HashMap; pub fn compile_sourcedir(source_dir: &str) -> Result, CrudLangError> { let mut registry = HashMap::new();