1
1
Fork 0
mirror of https://github.com/azur1s/bobbylisp.git synced 2024-10-16 02:37:40 -05:00

some (h)ir

This commit is contained in:
Natapat Samutpong 2022-03-07 03:45:09 +07:00
parent 23f1edfea4
commit e38d26ccb2
7 changed files with 77 additions and 21 deletions

8
Cargo.lock generated
View file

@ -140,6 +140,7 @@ dependencies = [
"ariadne",
"chumsky",
"clap",
"hir",
"lexer",
"parser",
]
@ -159,6 +160,13 @@ dependencies = [
"libc",
]
[[package]]
name = "hir"
version = "0.1.0"
dependencies = [
"parser",
]
[[package]]
name = "indexmap"
version = "1.8.0"

View file

@ -3,4 +3,5 @@ members = [
"crates/main",
"crates/lexer",
"crates/parser",
"crates/hir",
]

10
crates/hir/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "hir"
license = "MIT OR Apache-2.0"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
parser = { path = "../parser" }

49
crates/hir/src/lib.rs Normal file
View file

@ -0,0 +1,49 @@
use std::ops::Range;
use parser::Expr;
#[derive(Debug)]
pub enum Value { Int(i64), Float(f64), Bool(bool), String(String), Ident(String) }
#[derive(Debug)]
pub enum IRKind {
Define { name: String, type_hint: String, value: Box<Self> },
Fun { name: String, return_type_hint: String, args: Vec<(String, String)>, body: Box<Self> },
Call { name: String, args: Vec<Self> },
Do { body: Box<Self> },
If { cond: Box<Self>, body: Box<Self>, else_body: Box<Self> },
Value { value: Value },
Binary { op: String, left: Box<Self>, right: Box<Self> },
}
#[derive(Debug)]
pub struct IR {
pub kind: IRKind,
pub span: Range<usize>
}
impl IR {
pub fn new(kind: IRKind, span: Range<usize>) -> Self {
Self { kind, span }
}
}
pub fn ast_to_ir(ast: Vec<(Expr, Range<usize>)>) -> Vec<IR> {
let mut irs = Vec::new();
for expr in ast {
let ir_kind = expr_to_ir(&expr.0);
let ir = IR::new(ir_kind, expr.1);
irs.push(ir);
}
irs
}
pub fn expr_to_ir(expr: &Expr) -> IRKind {
match expr {
Expr::Let { name, type_hint, value } => {
let value = expr_to_ir(&value.0);
IRKind::Define { name: name.clone(), type_hint: type_hint.clone(), value: Box::new(value) }
},
Expr::Int(value) => IRKind::Value { value: Value::Int(*value) },
_ => { dbg!(expr); todo!() }
}
}

View file

@ -8,5 +8,6 @@ edition = "2021"
clap = { version = "3.0.14", features = ["derive"] }
lexer = { path = "../lexer" }
parser = { path = "../parser" }
hir = { path = "../hir" }
chumsky = "0.8.0"
ariadne = "0.1.5"

View file

@ -4,6 +4,7 @@ use clap::Parser as ArgParser;
use ariadne::{Report, ReportKind, Label, Source, Color, Fmt};
use lexer::lex;
use parser::parse;
use hir::ast_to_ir;
pub mod args;
use args::{Args, Options};
@ -25,6 +26,7 @@ fn main() {
let (tokens, lex_error) = lex(src.clone());
let (ast, parse_error) = parse(tokens.unwrap(), src.chars().count());
// Report errors.
lex_error.into_iter()
.map(|e| e.map(|e| e.to_string()))
.chain(parse_error.into_iter().map(|e| e.map(|tok| tok.to_string())))
@ -84,9 +86,6 @@ fn main() {
.fg(Color::Red)
))
.with_color(Color::Red)
)
.with_help(
"You might have forgotten to end a previous line with semicolon"
),
_ => {
println!("{:?}", e);
@ -99,7 +98,11 @@ fn main() {
match ast {
Some(ast) => {
println!("{:#?}", ast);
// Convert the AST to HIR.
let ir = ast_to_ir(ast);
// Print the HIR.
println!("{:#?}", ir);
},
None => {
log(2, "Failed to parse.");

View file

@ -1,17 +1 @@
-- Variables
let foo: Int = 1;
let bar: String = "bar";
-- Functions
fun add (lhs: Int) (rhs: Int): Int = lhs + rhs;
fun add_2 (lhs: Int) (rhs: Int): Int = do
let a: Int = lhs + rhs;
let b: Int = a + lhs;
return b;
end;
-- Entry point (maybe)
fun main: Void = do
print(add(34, 35));
return 0;
end;
let foo: int = 1;