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:
parent
23f1edfea4
commit
e38d26ccb2
8
Cargo.lock
generated
8
Cargo.lock
generated
|
@ -140,6 +140,7 @@ dependencies = [
|
||||||
"ariadne",
|
"ariadne",
|
||||||
"chumsky",
|
"chumsky",
|
||||||
"clap",
|
"clap",
|
||||||
|
"hir",
|
||||||
"lexer",
|
"lexer",
|
||||||
"parser",
|
"parser",
|
||||||
]
|
]
|
||||||
|
@ -159,6 +160,13 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hir"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"parser",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
|
|
|
@ -3,4 +3,5 @@ members = [
|
||||||
"crates/main",
|
"crates/main",
|
||||||
"crates/lexer",
|
"crates/lexer",
|
||||||
"crates/parser",
|
"crates/parser",
|
||||||
|
"crates/hir",
|
||||||
]
|
]
|
10
crates/hir/Cargo.toml
Normal file
10
crates/hir/Cargo.toml
Normal 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
49
crates/hir/src/lib.rs
Normal 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!() }
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,5 +8,6 @@ edition = "2021"
|
||||||
clap = { version = "3.0.14", features = ["derive"] }
|
clap = { version = "3.0.14", features = ["derive"] }
|
||||||
lexer = { path = "../lexer" }
|
lexer = { path = "../lexer" }
|
||||||
parser = { path = "../parser" }
|
parser = { path = "../parser" }
|
||||||
|
hir = { path = "../hir" }
|
||||||
chumsky = "0.8.0"
|
chumsky = "0.8.0"
|
||||||
ariadne = "0.1.5"
|
ariadne = "0.1.5"
|
|
@ -4,6 +4,7 @@ use clap::Parser as ArgParser;
|
||||||
use ariadne::{Report, ReportKind, Label, Source, Color, Fmt};
|
use ariadne::{Report, ReportKind, Label, Source, Color, Fmt};
|
||||||
use lexer::lex;
|
use lexer::lex;
|
||||||
use parser::parse;
|
use parser::parse;
|
||||||
|
use hir::ast_to_ir;
|
||||||
|
|
||||||
pub mod args;
|
pub mod args;
|
||||||
use args::{Args, Options};
|
use args::{Args, Options};
|
||||||
|
@ -25,6 +26,7 @@ fn main() {
|
||||||
let (tokens, lex_error) = lex(src.clone());
|
let (tokens, lex_error) = lex(src.clone());
|
||||||
let (ast, parse_error) = parse(tokens.unwrap(), src.chars().count());
|
let (ast, parse_error) = parse(tokens.unwrap(), src.chars().count());
|
||||||
|
|
||||||
|
// Report errors.
|
||||||
lex_error.into_iter()
|
lex_error.into_iter()
|
||||||
.map(|e| e.map(|e| e.to_string()))
|
.map(|e| e.map(|e| e.to_string()))
|
||||||
.chain(parse_error.into_iter().map(|e| e.map(|tok| tok.to_string())))
|
.chain(parse_error.into_iter().map(|e| e.map(|tok| tok.to_string())))
|
||||||
|
@ -84,9 +86,6 @@ fn main() {
|
||||||
.fg(Color::Red)
|
.fg(Color::Red)
|
||||||
))
|
))
|
||||||
.with_color(Color::Red)
|
.with_color(Color::Red)
|
||||||
)
|
|
||||||
.with_help(
|
|
||||||
"You might have forgotten to end a previous line with semicolon"
|
|
||||||
),
|
),
|
||||||
_ => {
|
_ => {
|
||||||
println!("{:?}", e);
|
println!("{:?}", e);
|
||||||
|
@ -99,7 +98,11 @@ fn main() {
|
||||||
|
|
||||||
match ast {
|
match ast {
|
||||||
Some(ast) => {
|
Some(ast) => {
|
||||||
println!("{:#?}", ast);
|
// Convert the AST to HIR.
|
||||||
|
let ir = ast_to_ir(ast);
|
||||||
|
|
||||||
|
// Print the HIR.
|
||||||
|
println!("{:#?}", ir);
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
log(2, "Failed to parse.");
|
log(2, "Failed to parse.");
|
||||||
|
|
|
@ -1,17 +1 @@
|
||||||
-- Variables
|
let foo: int = 1;
|
||||||
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;
|
|
Loading…
Reference in a new issue