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

Compare commits

...

2 commits

Author SHA1 Message Date
Natapat Samutpong 1e20eb89c3 update misc stuff 2022-03-07 03:53:44 +07:00
Natapat Samutpong e38d26ccb2 some (h)ir 2022-03-07 03:45:09 +07:00
9 changed files with 80 additions and 27 deletions

8
Cargo.lock generated
View file

@ -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"

View file

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

1
FUNDING.yml Normal file
View file

@ -0,0 +1 @@
ko_fi: azur1s

View file

@ -1,7 +1,7 @@
# Hades # Hades
Programming language that compiles to JavaScript Programming language that compiles to JavaScript!
Note: The syntax can still be changed and also the compile target (I'm still finding out what target will suit this the best) if you have an idea, feel free to create an issues about it. Note: Everything in this project can be changed at anytime! (I'm still finding out what work best for lots of thing) if you have an idea, feel free to create an issues about it, or even create a PR! (I'd be very happy)
# Prerequistie # Prerequistie
- `node` or any JavaScript runner - `node` or any JavaScript runner
@ -16,8 +16,4 @@ Note: The syntax can still be changed and also the compile target (I'm still fin
# License # License
Hades is licensed under both [MIT license](https://github.com/azur1s/hades/blob/master/LICENSE-MIT) and [Apache License](https://github.com/azur1s/hades/blob/master/LICENSE-APACHE) Hades is licensed under both [MIT license](https://github.com/azur1s/hades/blob/master/LICENSE-MIT) and [Apache License](https://github.com/azur1s/hades/blob/master/LICENSE-APACHE)
# Support
This is just a project for fun. If you wish to support me, you can do it through:
- [Kofi](https://ko-fi.com/azur1s)
Anything helps! :D Anything helps! :D

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"] } 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"

View file

@ -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.");

View file

@ -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;