Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions euler/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{env, fs};
use std::{env, fs, path::PathBuf};

use clap::{self, Args, Parser, Subcommand, ValueEnum};
use mathic::{
Expand All @@ -21,8 +21,15 @@ struct MathiCLI {

#[derive(Debug, Subcommand)]
enum Command {
New { project_name: String },
New {
project_name: String,
},
Run(CompilerOptionsArgs),
Path {
path: PathBuf,
#[clap(flatten)]
opts: CompilerOptionsArgs,
},
}

#[derive(Debug, Clone, Args)]
Expand Down Expand Up @@ -74,6 +81,7 @@ fn main() -> Result<(), EulerError> {
Command::Run(compiler_opts) => {
compile_project(compiler_opts.into())?;
}
Command::Path { path, opts } => compile_path(path, opts.into())?,
};

Ok(())
Expand Down Expand Up @@ -133,3 +141,28 @@ fn compile_project(compiler_opts: CompilerOpts) -> Result<(), EulerError> {

Ok(())
}

fn compile_path(path: PathBuf, compiler_opts: CompilerOpts) -> Result<(), EulerError> {
let compiler = MathicCompiler::new()?;

let module = match compiler.compile_path(&path, compiler_opts) {
Ok(modules) => modules,
Err(MathicError::CompilationFailed) => {
compiler.diagnostics().print_all()?;
std::process::exit(1);
}
Err(e) => {
return Err(EulerError::from(e));
}
};

let executor = MathicJITExecutor::new(vec![module], compiler_opts)?;

tracing::debug!("Executor Created");
let result = executor.call_function("main::main");

tracing::debug!("Execution Done");
println!("RESULT: {:?}", result);

Ok(())
}
34 changes: 34 additions & 0 deletions examples/structs/struct_methods.mth
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
struct Point {
x: u32,
y: u32
}

expand Point {
df new(x: u32, y: u32) Point {
return Point {
x: x,
y: y
};
}

df add(self, rhs: Point) Point {
return Point {
x: self.x + rhs.x,
y: self.y + rhs.y
};
}
}

df main() {
let point_1: Point = Point {
x: 5,
y: 5
};

let point_2: Point = Point {
x: 10,
y: 10
};

return point_1.add(point_2);
}
9 changes: 7 additions & 2 deletions grammar.ebnf
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ program = top_decl { top_decl } ;
top_decl = func_decl
| struct_decl
| imports_decls
| expand_decl
;
imports_decls = 'imp' import_path ';' ;
func_decl = 'df' IDENT '(' [ param_list ] ')' [ type ] block ;
struct_decl = 'struct' IDENT '{' [ struct_fields ] '}' ;
expand_decl = 'expand' path '{' [ func_decl ] '}' ;


(* ================================================================ *)
Expand All @@ -32,6 +34,7 @@ struct_decl = 'struct' IDENT '{' [ struct_fields ] '}' ;

declaration = func_decl
| struct_decl
| expand_decl
| var_decl
| sym_decl
;
Expand Down Expand Up @@ -90,7 +93,8 @@ factor = unary { ( '*' | '/' ) unary } ;
unary = ( '!' | '-' ) unary
| call
;
call = primary { '(' [ arg_list ] ')' | '.' IDENT
call = primary { '(' [ arg_list ] ')'
| '.' IDENT [ (' [ arg_list ] ')' ]
| '[' bracket_args ']' } ;
bracket_args = substitution ;
struct_init = '{' IDENT ':' expr { ',' IDENT ':' expr } '}' ;
Expand All @@ -102,7 +106,8 @@ primary = 'true' | 'false' | path | INT | FLOAT | STRING | '(' expr ')' ;
(* Utilities *)
(* ================================================================ *)

param_list = ( IDENT ':' type ) { ',' ( IDENT ':' type ) } ;
param_list = [ 'self' ',' ] param_list
| ( IDENT ':' type ) { ',' ( IDENT ':' type ) } ;
struct_fields = [ 'pub' ] IDENT ':' type { ',' [ 'pub' ] IDENT ':' type } ;
arg_list = expr { ',' expr } ;
import_path = IDENT
Expand Down
3 changes: 2 additions & 1 deletion src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,8 @@ impl MathicCompiler {
}
}
};

dbg!(ast);
todo!();
// AST lowering and semantic checks.
let ir = match lowering::lower_program(&ast) {
Ok(ir) => ir,
Expand Down
6 changes: 6 additions & 0 deletions src/diagnostics/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ pub enum ExpectedToken {
Custom(String),
}

impl From<Token> for ExpectedToken {
fn from(value: Token) -> Self {
Self::Token(value)
}
}

impl Display for ExpectedToken {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Expand Down
12 changes: 8 additions & 4 deletions src/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ pub fn lower_program(program: &IrModule) -> Result<Ir, LoweringError> {
// of a not yet declared function.
for item in program.items.iter() {
match item {
TopLevelItem::Func(f) => ir_builder.decl_table.add_func_decl(f.clone(), None)?,
TopLevelItem::ExpandBlock(_) => todo!(),
TopLevelItem::Func(f) => ir_builder.decl_table.add_func_decl(f.clone(), None, None)?,
TopLevelItem::Import(imp) => lower_import(&mut ir_builder, imp)?,
TopLevelItem::Struct(s) => ir_builder.decl_table.add_struct_decl(s.clone(), None)?,
}
Expand Down Expand Up @@ -110,7 +111,7 @@ fn lower_import(ir_builder: &mut IrBuilder, import_path: &Path) -> Result<(), Lo
TopLevelItem::Func(func) => {
ir_builder
.decl_table
.add_func_decl(func.clone(), Some(module_idx))?;
.add_func_decl(func.clone(), None, Some(module_idx))?;
utils::add_extern_function(
ir_builder,
&module.module_name,
Expand Down Expand Up @@ -168,7 +169,9 @@ fn lower_top_level_function(
// of a not yet declared function.
for stmt in body.iter() {
if let StmtKind::Decl(DeclStmt::Func(f)) = &stmt.kind {
func_builder.decl_table.add_func_decl(f.clone(), None)?;
func_builder
.decl_table
.add_func_decl(f.clone(), None, None)?;
}
}

Expand All @@ -178,7 +181,7 @@ fn lower_top_level_function(

let func = func_builder.build();

ir_builder.add_function(func);
ir_builder.add_function(func, None);

Ok(())
}
Expand Down Expand Up @@ -277,5 +280,6 @@ pub fn lower_top_level_ast_type(
}
}
}
AstType::SelfType => todo!(),
})
}
4 changes: 2 additions & 2 deletions src/lowering/ast_lowering/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ pub fn lower_inner_function(
for stmt in body.iter() {
match &stmt.kind {
StmtKind::Decl(DeclStmt::Func(f)) => {
inner_func.decl_table.add_func_decl(f.clone(), None)?
inner_func.decl_table.add_func_decl(f.clone(), None, None)?
}
StmtKind::Decl(DeclStmt::Struct(s)) => {
inner_func.decl_table.add_struct_decl(s.clone(), None)?
Expand All @@ -170,7 +170,7 @@ pub fn lower_inner_function(

let inner_func = inner_func.build();

func.sym_table.add_function(inner_func);
func.sym_table.add_function(inner_func, None);

Ok(())
}
2 changes: 2 additions & 0 deletions src/lowering/ast_lowering/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub fn lower_expr(
field_name,
rhs,
} => lower_struct_set(func, lhs, field_name, rhs, expr.span)?,
ExprStmtKind::MethodCall { callee: _, args: _ } => unimplemented!(),
};

Ok((
Expand Down Expand Up @@ -821,6 +822,7 @@ fn lower_expression_type(
None => func.get_or_insert_global_type_idx(MathicType::Void),
}
}
ExprStmtKind::MethodCall { callee: _, args: _ } => unimplemented!(),
ExprStmtKind::Group(expr_stmt) => lower_expression_type(func, &expr_stmt.kind, None, span)?,
ExprStmtKind::Index { .. } => todo!(),
ExprStmtKind::Logical { .. } => func.get_or_insert_global_type_idx(MathicType::Bool),
Expand Down
1 change: 1 addition & 0 deletions src/lowering/ast_lowering/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ fn lower_declaration(
DeclStmt::Struct(struct_decl) => {
let _ = lower_inner_struct(func, struct_decl)?;
}
DeclStmt::ExpandDecl(expand_block_) => unimplemented!(),
DeclStmt::Sym(sym_decl) => lower_sym_decl(func, sym_decl, *span)?,
DeclStmt::Func(func_decl) => lower_inner_function(func, func_decl, *span)?,
}
Expand Down
10 changes: 7 additions & 3 deletions src/lowering/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
diagnostics::LoweringError,
lowering::ir::{
adts::Adt,
function::Function,
function::{FuncId, Function},
symbols::{DeclTable, SymbolTableBuilder, TypeIndex},
types::MathicType,
},
Expand Down Expand Up @@ -67,8 +67,12 @@ impl IrBuilder {
}
}

pub fn add_function(&mut self, func: Function) {
self.sym_table.functions.insert(func.name.clone(), func);
pub fn add_function(&mut self, func: Function, method_of: Option<TypeIndex>) {
let func_id = FuncId {
name: func.name.clone(),
method_of,
};
self.sym_table.functions.insert(func_id, func);
}

pub fn get_type(&self, idx: TypeIndex, span: Span) -> Result<MathicType, LoweringError> {
Expand Down
17 changes: 13 additions & 4 deletions src/lowering/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ pub enum LocalKind {

/// MATHIR's representation of local variables.
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct Local {
pub local_idx: usize,
pub kind: LocalKind,
Expand All @@ -35,9 +34,14 @@ pub struct Local {
pub symbols: HashSet<usize>,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FuncId {
pub name: String,
pub method_of: Option<TypeIndex>,
}

/// MATHIR's representation of a function.
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct Function {
pub name: String,
sym_table: SymbolTable,
Expand Down Expand Up @@ -147,9 +151,14 @@ impl<'ir> FunctionBuilder<'ir> {
name: &str,
span: Span,
) -> Result<(FuncDecl, Option<usize>), LoweringError> {
match self.decl_table.get_function_decl(name).cloned() {
match self.decl_table.get_function_decl(name, None).cloned() {
Some(f) => Ok(f),
None => match self.ir_builder.decl_table.get_function_decl(name).cloned() {
None => match self
.ir_builder
.decl_table
.get_function_decl(name, None)
.cloned()
{
Some(f) => Ok(f),
None => Err(LoweringError::UndeclaredFunction {
name: name.to_string(),
Expand Down
Loading
Loading