compile statements (WIP)

refactor_anto
Sebastien Bourdeauducq 2020-03-27 23:47:40 +08:00
parent 8b7b012b27
commit f9a56c7d8f
1 changed files with 25 additions and 13 deletions

View File

@ -19,18 +19,21 @@ use std::path::Path;
enum CompileErrorKind {
Unsupported(&'static str),
MissingTypeAnnotation,
UnknownTypeAnnotation
UnknownTypeAnnotation,
Internal(&'static str)
}
impl fmt::Display for CompileErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CompileErrorKind::Unsupported(feature)
=> write!(f, "The following Python feature is not supported by NAC3 {}: ", feature),
=> write!(f, "The following Python feature is not supported by NAC3: {}", feature),
CompileErrorKind::MissingTypeAnnotation
=> write!(f, "Missing type annotation"),
CompileErrorKind::UnknownTypeAnnotation
=> write!(f, "Unknown type annotation"),
CompileErrorKind::Internal(details)
=> write!(f, "Internal compiler error: {}", details),
}
}
}
@ -148,6 +151,9 @@ impl<'ctx> CodeGen<'ctx> {
let y = function.get_nth_param(1).unwrap().into_int_value();
let sum = self.builder.build_int_add(x, y, "sum");
self.builder.build_return(Some(&sum));
for statement in body.iter() {
self.compile_statement(statement)?;
}
Ok(())
}
@ -156,22 +162,28 @@ impl<'ctx> CodeGen<'ctx> {
use ast::StatementType::*;
match &statement.node {
FunctionDef {
is_async,
name,
args,
body,
decorator_list,
returns,
} => {
self.compile_function_def(name, args, body, decorator_list, returns, *is_async)?;
},
Pass => (),
_ => return Err(self.compile_error(CompileErrorKind::Unsupported("special statement"))),
}
Ok(())
}
fn compile_toplevel(&mut self, statement: &ast::Statement) -> CompileResult<()> {
self.set_source_location(statement.location);
if let ast::StatementType::FunctionDef {
is_async,
name,
args,
body,
decorator_list,
returns,
} = &statement.node {
self.compile_function_def(name, args, body, decorator_list, returns, *is_async)
} else {
Err(self.compile_error(CompileErrorKind::Internal("top-level is not a function definition")))
}
}
fn output(&self) {
let triple = TargetTriple::create("riscv32-none-linux-gnu");
let target = Target::from_triple(&triple)
@ -204,7 +216,7 @@ fn main() {
let context = Context::create();
let mut codegen = CodeGen::new(&context);
match codegen.compile_statement(&ast.statements[0]) {
match codegen.compile_toplevel(&ast.statements[0]) {
Ok(_) => (),
Err(err) => { println!("{}", err); return; }
}