Skip to content
Snippets Groups Projects
Commit 97ec6d48 authored by Per's avatar Per
Browse files

block works (to some extent)

parent 134b920c
No related branches found
No related tags found
No related merge requests found
...@@ -33,7 +33,8 @@ fn main() -> Result<(), Box<dyn Error>> { ...@@ -33,7 +33,8 @@ fn main() -> Result<(), Box<dyn Error>> {
match parse_block(Span::new( match parse_block(Span::new(
" "
{ {
return 2 + 3 let abba : i32 = 7;
return 2 + abba
} }
", ",
)) { )) {
...@@ -50,6 +51,7 @@ fn main() -> Result<(), Box<dyn Error>> { ...@@ -50,6 +51,7 @@ fn main() -> Result<(), Box<dyn Error>> {
builder: &builder, builder: &builder,
module: &module, module: &module,
fn_value_opt: Some(function), fn_value_opt: Some(function),
variables: HashMap::new(),
//&fpm, //&fpm,
}; };
let res = compiler.compile_block(prog); let res = compiler.compile_block(prog);
...@@ -74,8 +76,7 @@ pub struct Compiler<'a> { ...@@ -74,8 +76,7 @@ pub struct Compiler<'a> {
// pub fpm: &'a PassManager<FunctionValue>, // pub fpm: &'a PassManager<FunctionValue>,
pub module: &'a Module, pub module: &'a Module,
// pub function: &'a Func<'a>, // pub function: &'a Func<'a>,
variables: HashMap<String, PointerValue>,
// variables: HashMap<String, PointerValue>,
fn_value_opt: Option<FunctionValue>, fn_value_opt: Option<FunctionValue>,
} }
...@@ -94,6 +95,16 @@ impl<'a> Compiler<'a> { ...@@ -94,6 +95,16 @@ impl<'a> Compiler<'a> {
fn compile_expr(&self, expr: &SpanExpr) -> IntValue { fn compile_expr(&self, expr: &SpanExpr) -> IntValue {
match expr.1.clone() { match expr.1.clone() {
Expr::Id(id) => match self.variables.get(&id) {
Some(var) => {
self.builder.build_load(*var, &id).into_int_value()
}
None => panic!(
"Could not find a matching variable.
{} in {:?}",
id, self.variables
),
},
Expr::Num(i) => self.context.i32_type().const_int(i as u64, false), Expr::Num(i) => self.context.i32_type().const_int(i as u64, false),
Expr::BinOp(op, l, r) => { Expr::BinOp(op, l, r) => {
...@@ -109,7 +120,7 @@ impl<'a> Compiler<'a> { ...@@ -109,7 +120,7 @@ impl<'a> Compiler<'a> {
} }
/// Creates a new stack allocation instruction in the entry block of the function. /// Creates a new stack allocation instruction in the entry block of the function.
fn create_entry_block_alloca(&self, name: &str) -> PointerValue { fn create_entry_block_alloca(&mut self, name: &str) -> PointerValue {
let builder = self.context.create_builder(); let builder = self.context.create_builder();
let entry = self.fn_value().get_first_basic_block().unwrap(); let entry = self.fn_value().get_first_basic_block().unwrap();
...@@ -118,12 +129,13 @@ impl<'a> Compiler<'a> { ...@@ -118,12 +129,13 @@ impl<'a> Compiler<'a> {
Some(first_instr) => builder.position_before(&first_instr), Some(first_instr) => builder.position_before(&first_instr),
None => builder.position_at_end(&entry), None => builder.position_at_end(&entry),
} }
let alloca = builder.build_alloca(self.context.i32_type(), name);
builder.build_alloca(self.context.f64_type(), name) self.variables.insert(name.to_string(), alloca);
alloca
} }
fn compile_cmd(&self, cmd: &Cmd) -> (InstructionValue, bool) { fn compile_cmd(&mut self, cmd: &Cmd) -> (InstructionValue, bool) {
println!("{:?}", cmd); // println!("{:?}", cmd);
match cmd { match cmd {
// Cmd::Assign(lexp, rexp) => { // Cmd::Assign(lexp, rexp) => {
// let rval = eval_expr(rexp, mem, venv, fenv); // let rval = eval_expr(rexp, mem, venv, fenv);
...@@ -146,33 +158,22 @@ impl<'a> Compiler<'a> { ...@@ -146,33 +158,22 @@ impl<'a> Compiler<'a> {
// } // }
// } // }
// } // }
// Cmd::Let(_, id, _, exp) => { Cmd::Let(_, id, _, exp) => {
// let val = eval_expr(exp, stack, fenv); let exp = self.compile_expr(exp);
// println!("val {:?}", val); println!("\n-- let id.fragment {}\n", id.fragment);
let alloca = self.create_entry_block_alloca(id.fragment);
// // let addr = mem.alloc(); // get new allocation slot let store = self.builder.build_store(alloca, exp);
// // mem.Menv.insert(addr, val); // write the new value (store, false)
// // venv.insert(id.to_owned(), addr); }
// // dump("after Let", mem, venv);
// None
// }
Cmd::Return(exp) => { Cmd::Return(exp) => {
let expr = self.compile_expr(exp); let expr = self.compile_expr(exp);
(self.builder.build_return(Some(&expr)), true) (self.builder.build_return(Some(&expr)), true)
} }
// Cmd::While(exp, body) => {
// while get_bool(eval_expr(exp, mem, venv, fenv)) {
// if let Some(retv) = eval_body(body.to_vec(), mem, venv, fenv) {
// return Some(retv);
// }
// }
// None
// }
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
pub fn compile_block(&self, cmds: Vec<Cmd>) -> InstructionValue { pub fn compile_block(&mut self, cmds: Vec<Cmd>) -> InstructionValue {
for c in &cmds { for c in &cmds {
let (cmd, ret) = self.compile_cmd(c); let (cmd, ret) = self.compile_cmd(c);
if ret { if ret {
......
...@@ -6,7 +6,9 @@ use std::slice::Iter; ...@@ -6,7 +6,9 @@ use std::slice::Iter;
use nom::{ use nom::{
branch::alt, branch::alt,
bytes::complete::tag, bytes::complete::tag,
character::complete::{alpha1, alphanumeric0, char, digit1, multispace0, multispace1}, character::complete::{
alpha1, alphanumeric0, char, digit1, multispace0, multispace1,
},
combinator::{cut, map, opt}, combinator::{cut, map, opt},
error::ParseError, error::ParseError,
multi::{many1, separated_list}, multi::{many1, separated_list},
...@@ -15,7 +17,8 @@ use nom::{ ...@@ -15,7 +17,8 @@ use nom::{
}; };
use crate::ast::{ use crate::ast::{
Block, Cmd, Expr, Func, Item, Mutability, Op, Prog, Span, SpanCmd, SpanExpr, SpanId, Type, Block, Cmd, Expr, Func, Item, Mutability, Op, Prog, Span, SpanCmd,
SpanExpr, SpanId, Type,
}; };
pub fn parse_i32(i: Span) -> IResult<Span, (Span, i32)> { pub fn parse_i32(i: Span) -> IResult<Span, (Span, i32)> {
...@@ -55,9 +58,13 @@ pub fn parse_id(i: Span) -> IResult<Span, Span> { ...@@ -55,9 +58,13 @@ pub fn parse_id(i: Span) -> IResult<Span, Span> {
// an identifier needs to start with one or more alphas (head) // an identifier needs to start with one or more alphas (head)
// followed by zero or more alphanumerics (tail) // followed by zero or more alphanumerics (tail)
map( map(
preceded(multispace0, tuple((alpha1, alphanumeric0))), preceded(multispace0, tuple((alpha1, alphanumeric0, tag("")))),
// we concatenate the head and tail into a single String // we concatenate the head and tail into a single String
|(_, _)| i, // head.to_string() + &tail.to_string(), |(_, _, end): (Span, Span, Span)| {
let mut res = i;
res.fragment = &i.fragment[..(end.offset - i.offset)];
res
},
)(i) )(i)
} }
...@@ -67,7 +74,10 @@ fn parse_terminal(i: Span) -> IResult<Span, SpanToken> { ...@@ -67,7 +74,10 @@ fn parse_terminal(i: Span) -> IResult<Span, SpanToken> {
map(tag("true"), |s| (s, Token::Bool(true))), map(tag("true"), |s| (s, Token::Bool(true))),
map(tag("false"), |s| (s, Token::Bool(false))), map(tag("false"), |s| (s, Token::Bool(false))),
map( map(
tuple((parse_id, parse_par(separated_list(char(','), parse_tokens)))), tuple((
parse_id,
parse_par(separated_list(char(','), parse_tokens)),
)),
|(s, t)| (s, Token::Call(s.to_string(), t)), |(s, t)| (s, Token::Call(s.to_string(), t)),
), ),
map(parse_id, |s: Span| (s, Token::Id(s.to_string()))), map(parse_id, |s: Span| (s, Token::Id(s.to_string()))),
...@@ -103,12 +113,17 @@ fn compute_atom<'a>(t: &mut Peekable<Iter<SpanToken<'a>>>) -> SpanExpr<'a> { ...@@ -103,12 +113,17 @@ fn compute_atom<'a>(t: &mut Peekable<Iter<SpanToken<'a>>>) -> SpanExpr<'a> {
.collect(); .collect();
(*s, Expr::Call(id.to_string(), v)) (*s, Expr::Call(id.to_string(), v))
} }
Some((s, Token::Op(op))) => (*s, Expr::UnaryOp(*op, Box::new(climb(t, 4)))), // assume highest precedence Some((s, Token::Op(op))) => {
(*s, Expr::UnaryOp(*op, Box::new(climb(t, 4))))
} // assume highest precedence
_ => panic!("error in compute atom"), _ => panic!("error in compute atom"),
} }
} }
fn climb<'a>(t: &mut Peekable<Iter<SpanToken<'a>>>, min_prec: u8) -> SpanExpr<'a> { fn climb<'a>(
t: &mut Peekable<Iter<SpanToken<'a>>>,
min_prec: u8,
) -> SpanExpr<'a> {
let mut result: SpanExpr = compute_atom(t); let mut result: SpanExpr = compute_atom(t);
loop { loop {
...@@ -154,7 +169,9 @@ fn parse_if(i: Span) -> IResult<Span, Cmd> { ...@@ -154,7 +169,9 @@ fn parse_if(i: Span) -> IResult<Span, Cmd> {
opt(preceded(preceded(multispace0, tag("else")), parse_block)), opt(preceded(preceded(multispace0, tag("else")), parse_block)),
))), ))),
), ),
|(pred, true_branch, maybe_false_branch)| Cmd::If(pred, true_branch, maybe_false_branch), |(pred, true_branch, maybe_false_branch)| {
Cmd::If(pred, true_branch, maybe_false_branch)
},
)(i) )(i)
} }
...@@ -307,22 +324,34 @@ fn get_prec(op: &Op) -> (u8, Ass) { ...@@ -307,22 +324,34 @@ fn get_prec(op: &Op) -> (u8, Ass) {
} }
// helpers // helpers
fn parse_par<'a, O, F, E>(inner: F) -> impl Fn(Span<'a>) -> IResult<Span<'a>, O, E> fn parse_par<'a, O, F, E>(
inner: F,
) -> impl Fn(Span<'a>) -> IResult<Span<'a>, O, E>
where where
F: Fn(Span<'a>) -> IResult<Span<'a>, O, E>, F: Fn(Span<'a>) -> IResult<Span<'a>, O, E>,
E: ParseError<Span<'a>>, E: ParseError<Span<'a>>,
{ {
// delimited allows us to split up the input // delimited allows us to split up the input
// cut allwos us to consume the input (and prevent backtracking) // cut allwos us to consume the input (and prevent backtracking)
delimited(char('('), preceded(multispace0, inner), cut(char(')'))) delimited(
char('('),
preceded(multispace0, inner),
cut(preceded(multispace0, char(')'))),
)
} }
fn parse_sem<'a, O, F, E>(inner: F) -> impl Fn(Span<'a>) -> IResult<Span<'a>, O, E> fn parse_sem<'a, O, F, E>(
inner: F,
) -> impl Fn(Span<'a>) -> IResult<Span<'a>, O, E>
where where
F: Fn(Span<'a>) -> IResult<Span<'a>, O, E>, F: Fn(Span<'a>) -> IResult<Span<'a>, O, E>,
E: ParseError<Span<'a>>, E: ParseError<Span<'a>>,
{ {
// delimited allows us to split up the input // delimited allows us to split up the input
// cut allwos us to consume the input (and prevent backtracking) // cut allwos us to consume the input (and prevent backtracking)
delimited(char('{'), preceded(multispace0, inner), cut(char('}'))) delimited(
char('{'),
preceded(multispace0, inner),
cut(preceded(multispace0, char('}'))),
)
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment