Wire functions through everything, with some unimplemented, and add a basic scoped map.

This commit is contained in:
2023-10-07 11:06:28 +02:00
parent eba5227ebc
commit 736d27953f
18 changed files with 392 additions and 97 deletions

View File

@@ -1,7 +1,7 @@
use std::collections::HashMap;
use crate::eval::PrimitiveType;
use crate::ir::{Expression, Primitive, Program, Statement, Type, Value, ValueOrRef};
use crate::ir::{Expression, Primitive, Program, Statement, TopLevel, Type, Value, ValueOrRef};
use crate::syntax::ConstantType;
use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::{
@@ -120,12 +120,14 @@ impl<M: Module> Backend<M> {
// this is likely to become more cumbersome, and we'll want to separate
// these off. But for now, given the amount of tables we keep around to track
// state, it's easier to just include them.
for stmt in program.statements.drain(..) {
match stmt {
for item in program.items.drain(..) {
match item {
TopLevel::Function(_, _, _) => unimplemented!(),
// Print statements are fairly easy to compile: we just lookup the
// output buffer, the address of the string to print, and the value
// of whatever variable we're printing. Then we just call print.
Statement::Print(ann, t, var) => {
TopLevel::Statement(Statement::Print(ann, t, var)) => {
// Get the output buffer (or null) from our general compilation context.
let buffer_ptr = self.output_buffer_ptr();
let buffer_ptr = builder.ins().iconst(types::I64, buffer_ptr as i64);
@@ -163,7 +165,7 @@ impl<M: Module> Backend<M> {
}
// Variable binding is a little more con
Statement::Binding(_, var_name, _, value) => {
TopLevel::Statement(Statement::Binding(_, var_name, _, value)) => {
// Kick off to the `Expression` implementation to see what value we're going
// to bind to this variable.
let (val, etype) =