Skip to content

Commit

Permalink
Make errors better
Browse files Browse the repository at this point in the history
  • Loading branch information
didrikmunther committed Sep 24, 2024
1 parent fd4c3d6 commit a3e40a7
Show file tree
Hide file tree
Showing 19 changed files with 370 additions and 186 deletions.
9 changes: 5 additions & 4 deletions input.ro
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
__builtin fn printf(format: str, ...args: any);

fn add_two_numbers(a: int, b: any) {
fn add_two_numbers(a: int, b: int) {
let c = a + b;

let k: int = c;

printf("%i + %i = %i\n", a, b, c);
}


let a: int = 1;
let b: str = "hej";
let b: int = 5 + a;

add_two_numbers(
a,
b,
c
b
);
52 changes: 38 additions & 14 deletions out.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ def __compiler__with_regular_args(func):
def wrapper(*args):
n_args = __stack.pop()
args = [__stack.pop() for i in range(n_args)]
__stack.append(func(*args))
func(*args)

return wrapper


@__compiler__with_regular_args
def __builtin__printf(format, *args):
sys.stdout.write(format % args)
__intrinsic__stack_push(0)


__stack = []
Expand Down Expand Up @@ -45,10 +46,10 @@ def __intrinsic__stack_pop():
# boilerplate_start end

# Builtin function: printf
def __userf__5():
def __userf__6():
__builtin__printf()
# User function: add_two_numbers
def __userf__6():
def __userf__7():
__intrinsic__stack_pop()
_2_a = __intrinsic__stack_pop()
_3_b = __intrinsic__stack_pop()
Expand All @@ -57,47 +58,70 @@ def __userf__6():
__intrinsic__stack_add()
_4_c = __intrinsic__stack_pop()
__intrinsic__stack_push(_4_c)
_5_k = __intrinsic__stack_pop()
__intrinsic__stack_push(_4_c)
__intrinsic__stack_push(_3_b)
__intrinsic__stack_push(_2_a)
__intrinsic__stack_push(__global_data[1])
__intrinsic__stack_push(__global_data[0])
__intrinsic__stack_push(4)
# Procedure call: printf
__userf__5()
__userf__6()
__intrinsic__stack_pop()

__intrinsic__stack_push(0)
pass


def __setup():
global __global_data
__global_data = list(range(2))
__global_data[0] = "hej"
__global_data[1] = "%i + %i = %i\n"
__global_data = list(range(1))
__global_data[0] = "%i + %i = %i\n"

def __main():
__intrinsic__stack_push(1)
_0_a = __intrinsic__stack_pop()
__intrinsic__stack_push(__global_data[0])
__intrinsic__stack_push(_0_a)
__intrinsic__stack_push(5)
__intrinsic__stack_add()
_1_b = __intrinsic__stack_pop()
__intrinsic__stack_push(_1_b)
__intrinsic__stack_push(_0_a)
__intrinsic__stack_push(2)
# Procedure call: add_two_numbers
__userf__6()
__userf__7()
__intrinsic__stack_pop()

pass

# boilerplate_exit begin

if __name__ == "__main__":

def __push_init_args():
import sys

__intrinsic__stack_push(sys.argv)
__intrinsic__stack_push(len(sys.argv))
args = [
sys.argv,
len(sys.argv),
]

for arg in args:
__intrinsic__stack_push(arg)

__intrinsic__stack_push(len(args))


if __name__ == "__main__":
import sys

__push_init_args()
__setup()
sys.exit(__main())

__push_init_args()
status = __main()

print("stack", __stack)

sys.exit(status)


# boilerplate_exit end
Expand Down
3 changes: 2 additions & 1 deletion src/backend/python/boilerplate_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ def __compiler__with_regular_args(func):
def wrapper(*args):
n_args = __stack.pop()
args = [__stack.pop() for i in range(n_args)]
__stack.append(func(*args))
func(*args)

return wrapper


@__compiler__with_regular_args
def __builtin__printf(format, *args):
sys.stdout.write(format % args)
__intrinsic__stack_push(0)


__stack = []
Expand Down
27 changes: 23 additions & 4 deletions src/backend/python/boilerplate_exit.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
# boilerplate_exit begin

if __name__ == "__main__":

def __push_init_args():
import sys

__intrinsic__stack_push(sys.argv)
__intrinsic__stack_push(len(sys.argv))
args = [
sys.argv,
len(sys.argv),
]

for arg in args:
__intrinsic__stack_push(arg)

__intrinsic__stack_push(len(args))


if __name__ == "__main__":
import sys

__push_init_args()
__setup()
sys.exit(__main())

__push_init_args()
status = __main()

print("stack", __stack)

sys.exit(status)


# boilerplate_exit end
1 change: 1 addition & 0 deletions src/backend/python/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ impl Generator {
identifier: format!("__userf__{}", function.variable_id),
content: Box::new(Element::Block(vec![
self.get_program(content, program)?,
Element::Push("0".into()),
Element::Pass,
])),
});
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/error.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::program::{ir::ExpressedType, Program};
use super::program::{typ::ExpressedType, Program};
use crate::{
error::{RostError, RostErrorElement},
lexer::Keyword,
Expand Down Expand Up @@ -94,6 +94,7 @@ pub enum CompilerErrorKind {
WrongFunctionArguments(WrongFunctionArguments),
RedeclaredVariable(String, Range<usize>),
NotSupported(String),
UndefinedType(WrongType),
WrongAssignmentType {
got: WrongType,
typ: WrongType,
Expand Down Expand Up @@ -186,6 +187,9 @@ impl CompilerError {
),
]
}
CompilerErrorKind::UndefinedType(WrongType { content }) => {
vec![(format!("Undefined type: {content}"), self.pos.clone())]
}
CompilerErrorKind::WrongAssignmentType {
got,
typ,
Expand Down
61 changes: 42 additions & 19 deletions src/compiler/program/assignment.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use super::{
builder::Builder,
ir::{ExpressedType, Function, FunctionId, FunctionTemplate, FunctionTypeKind, Type},
ir::{Function, FunctionId, FunctionTemplate},
typ::{ExpressedType, FunctionTypeKind, Type, TypeKind},
Program,
};
use crate::{
compiler::{
error::{CompilerError, CompilerErrorKind, WrongType},
program::ir::{Instruction, InstructionKind, TypeKind, Variable, VariableId},
program::ir::{Instruction, InstructionKind, Variable, VariableId},
},
parser::{
definition::{ExpressionKind, Primary, VariableAssignment, VariableDeclaration},
Expand Down Expand Up @@ -144,28 +145,50 @@ impl Program {
let assignment_has_error = value.is_none();

let inferred_typ = self.infer_type(&declaration.right)?;
let picked_typ = declaration
.typ
.as_ref()
.and_then(|v| self.get_declared_type(v));

if let Some(picked_typ) = picked_typ {
if inferred_typ != picked_typ {
return Err(CompilerError::new(
declaration.right_pos.clone(),
CompilerErrorKind::WrongAssignmentType {
typ: WrongType::from_expressed_type(inferred_typ, self),
got: WrongType::from_expressed_type(picked_typ, self),
declaration_pos: declaration.typ.as_ref().map(|typ| typ.pos.clone()),
},
));

let assignment_typ = if let Some(declaration_typ) = &declaration.typ {
match self.get_declared_type(declaration_typ) {
None => {
self.add_error(CompilerError::new(
declaration_typ.pos.clone(),
CompilerErrorKind::UndefinedType(WrongType {
content: format!("{declaration_typ}"),
}),
));

self.get_intrinstic_type("unknown")
}
Some(picked_typ) => {
let is_unknown = match self.reverse_type_lookup.get(&inferred_typ.id) {
Some(identifier) => identifier == "unknown",
None => false,
};

if !is_unknown && inferred_typ != picked_typ {
self.add_error(CompilerError::new(
declaration.right_pos.clone(),
CompilerErrorKind::WrongAssignmentType {
got: WrongType::from_expressed_type(inferred_typ.clone(), self),
typ: WrongType::from_expressed_type(picked_typ, self),
declaration_pos: declaration
.typ
.as_ref()
.map(|typ| typ.pos.clone()),
},
));
}

inferred_typ
}
}
}
} else {
inferred_typ
};

let variable_id = self.insert_variable(
Variable {
identifier: declaration.identifier.clone(),
typ: inferred_typ,
typ: assignment_typ,
declaration_pos: declaration.identifier_pos.clone(),
assignment_has_error,
},
Expand Down
42 changes: 34 additions & 8 deletions src/compiler/program/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use crate::{

use super::{
builder::Builder,
ir::{Arithmetic, ExpressedType, Instruction, InstructionKind},
ir::{Arithmetic, Instruction, InstructionKind},
typ::{ExpressedType, TypeKind},
Program,
};

Expand Down Expand Up @@ -48,7 +49,7 @@ impl Program {
}
}

pub fn infer_type(&self, expr: &Expression) -> Result<ExpressedType, CompilerError> {
pub fn infer_type(&mut self, expr: &Expression) -> Result<ExpressedType, CompilerError> {
match &expr.kind {
ExpressionKind::Primary(primary) => match primary {
Primary::Identifier(ref identifier) => {
Expand All @@ -73,21 +74,46 @@ impl Program {
let left = self.infer_type(&binary.left)?;
let right = self.infer_type(&binary.right)?;

if left == right {
Ok(left)
} else {
Err(CompilerError::new(
let is_unknown =
[&left, &right]
.iter()
.any(|v| match &self.types.get(v.id).unwrap().kind {
TypeKind::Intrinsic { identifier } => identifier == "unknown",
_ => false,
});

if !is_unknown && left != right {
self.add_error(CompilerError::new(
binary.left.pos.clone(),
CompilerErrorKind::WrongBinaryExpressionTypes {
got: WrongType::from_expressed_type(left, self),
got: WrongType::from_expressed_type(left.clone(), self),
expected: WrongType::from_expressed_type(right, self),
expected_pos: binary.right.pos.clone(),
operator: binary.operator,
operator_pos: binary.operator_pos.clone(),
},
))
));

return Ok(self.get_intrinstic_type("unknown"));
}

Ok(left)

// if left == right {
// Ok(left)
// } else {
// Err(CompilerError::new(
// binary.left.pos.clone(),
// CompilerErrorKind::WrongBinaryExpressionTypes {
// got: WrongType::from_expressed_type(left, self),
// expected: WrongType::from_expressed_type(right, self),
// expected_pos: binary.right.pos.clone(),
// operator: binary.operator,
// operator_pos: binary.operator_pos.clone(),
// },
// ))
// }

// let inferred = self.infer_binary_result_type(&left, &right, binary.operator);
// let Some(typ) = inferred else {
// return Err(CompilerError::new(
Expand Down
Loading

0 comments on commit a3e40a7

Please sign in to comment.