mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Compare commits
2 commits
23f1edfea4
...
1e20eb89c3
Author | SHA1 | Date | |
---|---|---|---|
Natapat Samutpong | 1e20eb89c3 | ||
Natapat Samutpong | 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",
|
||||||
]
|
]
|
1
FUNDING.yml
Normal file
1
FUNDING.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ko_fi: azur1s
|
|
@ -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
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