mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
Compare commits
2 commits
7746dba3cc
...
00b97b9f3b
Author | SHA1 | Date | |
---|---|---|---|
Natapat Samutpong | 00b97b9f3b | ||
Natapat Samutpong | 1ce9b74190 |
|
@ -63,7 +63,8 @@ impl Codegen {
|
|||
"write_file" => { format!("writeFile({}, {}){}\n", self.gen_ir(&args[0], false), self.gen_ir(&args[1], false), semicolon!()) },
|
||||
"read" => { format!("read({}){}\n" , self.gen_ir(&args[0], false), semicolon!()) },
|
||||
"read_file" => { format!("readFile({}){}\n" , self.gen_ir(&args[0], false), semicolon!()) }
|
||||
"emit" => { format!("{}", self.gen_ir(&args[0], false).trim_start_matches('"').trim_end_matches('"')) },
|
||||
"emit" => { format!("{}", self.gen_ir(&args[0], false).trim_start_matches('"').trim_end_matches('"')) },
|
||||
"get" => { format!("{}[{}]", self.gen_ir(&args[0], false), self.gen_ir(&args[1], false)) },
|
||||
_ => unreachable!(format!("Unknown intrinsic: {}", name)) // Shoul be handled by lowering
|
||||
}
|
||||
},
|
||||
|
@ -145,6 +146,17 @@ impl Codegen {
|
|||
}
|
||||
},
|
||||
|
||||
IRKind::Vector { values } => {
|
||||
format!(
|
||||
"[{}]",
|
||||
values
|
||||
.iter()
|
||||
.map(|value| self.gen_ir(value, false))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
},
|
||||
|
||||
#[allow(unreachable_patterns)]
|
||||
_ => { dbg!(ir); todo!() },
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use std::ops::Range;
|
||||
use parser::Expr;
|
||||
|
||||
const INTRINSICS: [&str; 5] = [
|
||||
const INTRINSICS: [&str; 6] = [
|
||||
"write",
|
||||
"read",
|
||||
"write_file",
|
||||
"read_file",
|
||||
"emit",
|
||||
"get",
|
||||
];
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -47,7 +48,10 @@ pub enum IRKind {
|
|||
Case { cond: Box<Self>, cases: Vec<(Box<Self>, Box<Self>)>, default: Box<Self> },
|
||||
Unary { op: String, right: Box<Self> },
|
||||
Binary { op: String, left: Box<Self>, right: Box<Self> },
|
||||
|
||||
Value { value: Value },
|
||||
Vector { values: Vec<Self> },
|
||||
|
||||
Return { value: Box<Self> },
|
||||
}
|
||||
|
||||
|
@ -102,6 +106,9 @@ impl std::fmt::Display for IRKind {
|
|||
IRKind::Value { ref value } => {
|
||||
write!(f, "{}", value)
|
||||
},
|
||||
IRKind::Vector { ref values } => {
|
||||
write!(f, "[{}]", values.iter().map(|expr| expr.to_string()).collect::<Vec<_>>().join(" "))
|
||||
},
|
||||
IRKind::Return { ref value } => {
|
||||
write!(f, "(return {})", value)
|
||||
}
|
||||
|
@ -402,6 +409,18 @@ pub fn expr_to_ir(expr: &Expr) -> (Option<IRKind>, Option<LoweringError>) {
|
|||
Expr::Boolean(value) => (Some(IRKind::Value { value: Value::Boolean(*value) }), None),
|
||||
Expr::String(value) => (Some(IRKind::Value { value: Value::String(value.clone()) }), None),
|
||||
Expr::Identifier(value) => (Some(IRKind::Value { value: Value::Ident(value.clone()) }), None),
|
||||
|
||||
Expr::Vector(values) => {
|
||||
let mut lvalues = Vec::new();
|
||||
for value in values {
|
||||
let value = expr_to_ir(&value.0);
|
||||
if_err_return!(value.1);
|
||||
|
||||
lvalues.push(value.0.unwrap());
|
||||
}
|
||||
(Some(IRKind::Vector { values: lvalues }), None)
|
||||
},
|
||||
|
||||
// Probably will never happen because it is catched in parser
|
||||
Expr::Hole(start, end) => (None, Some(LoweringError {
|
||||
span: *start..*end,
|
||||
|
@ -418,6 +437,10 @@ fn gen_type_hint(type_hint: &str) -> String {
|
|||
"bool" => "boolean".to_string(),
|
||||
"string" => "string".to_string(),
|
||||
"void" => "void".to_string(),
|
||||
// TODO: Un-hardcode vector type
|
||||
"vec_int" => "number[]".to_string(),
|
||||
"vec_bool" => "boolean[]".to_string(),
|
||||
"vec_str" => "string[]".to_string(),
|
||||
_ => { dbg!(type_hint); todo!() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ pub enum Token {
|
|||
Dot, Comma,
|
||||
Colon, SemiColon,
|
||||
OpenParen, CloseParen,
|
||||
OpenBracket, CloseBracket,
|
||||
At,
|
||||
Hole,
|
||||
}
|
||||
|
@ -69,8 +70,12 @@ impl std::fmt::Display for Token {
|
|||
Token::Comma => write!(f, ","),
|
||||
Token::Colon => write!(f, ":"),
|
||||
Token::SemiColon => write!(f, ";"),
|
||||
|
||||
Token::OpenParen => write!(f, "("),
|
||||
Token::CloseParen => write!(f, ")"),
|
||||
Token::OpenBracket => write!(f, "["),
|
||||
Token::CloseBracket => write!(f, "]"),
|
||||
|
||||
Token::At => write!(f, "@"),
|
||||
Token::Hole => write!(f, "_"),
|
||||
}
|
||||
|
@ -112,6 +117,8 @@ pub fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = Simple<char>> {
|
|||
just(';').to(Token::SemiColon),
|
||||
just('(').to(Token::OpenParen),
|
||||
just(')').to(Token::CloseParen),
|
||||
just('[').to(Token::OpenBracket),
|
||||
just(']').to(Token::CloseBracket),
|
||||
just('@').to(Token::At),
|
||||
just('_').to(Token::Hole),
|
||||
));
|
||||
|
|
|
@ -8,6 +8,8 @@ pub enum Expr {
|
|||
Int(i64), Float(f64), Boolean(bool),
|
||||
String(String), Identifier(String),
|
||||
|
||||
Vector(Vec<Spanned<Self>>),
|
||||
|
||||
Unary { op: String, rhs: Box<Spanned<Self>> },
|
||||
Binary { lhs: Box<Spanned<Self>>, op: String, rhs: Box<Spanned<Self>> },
|
||||
Call { name: Box<Spanned<Self>>, args: Spanned<Vec<Spanned<Self>>> },
|
||||
|
@ -67,11 +69,23 @@ fn expr_parser() -> impl Parser<Token, Vec<Spanned<Expr>>, Error = Simple<Token>
|
|||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing();
|
||||
|
||||
let vector = expr.clone()
|
||||
.separated_by(just(Token::Comma))
|
||||
.allow_trailing()
|
||||
.delimited_by(
|
||||
just(Token::OpenBracket),
|
||||
just(Token::CloseBracket),
|
||||
)
|
||||
.map_with_span(|args, span| {
|
||||
(
|
||||
Expr::Vector(args),
|
||||
span,
|
||||
)
|
||||
});
|
||||
|
||||
let atom = literal
|
||||
.or(identifier.map(|(s, span)| (Expr::Identifier(s), span)))
|
||||
// .or(
|
||||
// expr.clone()
|
||||
// .delimited_by(just(Token::OpenParen), just(Token::CloseParen)))
|
||||
.or(vector)
|
||||
.labelled("atom");
|
||||
|
||||
let call = atom.clone()
|
||||
|
|
115
example/rule110.hz
Normal file
115
example/rule110.hz
Normal file
|
@ -0,0 +1,115 @@
|
|||
fun print_single (cell: bool): void = do
|
||||
case cell of
|
||||
| true -> @write("█");
|
||||
| else @write(" ");
|
||||
end;
|
||||
end;
|
||||
|
||||
fun print_vec (state: vec_bool) (length: int) (curr: int): void = do
|
||||
if curr == length then @write(""); else
|
||||
do
|
||||
@get(state, curr) |> print_single(_);
|
||||
print_vec(state, length, curr + 1);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
fun cell_merger (a: bool) (b: bool) (c: bool): bool = do
|
||||
if a then
|
||||
if b then
|
||||
if c then
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
end;
|
||||
else
|
||||
if c then
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
if b then
|
||||
if c then
|
||||
return true;
|
||||
else
|
||||
return true;
|
||||
end;
|
||||
else
|
||||
if c then
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
fun next (state: vec_bool) (pointer: int): bool = do
|
||||
case pointer of
|
||||
| 0 -> do
|
||||
let a: bool = false;
|
||||
let b: bool = @get(state, 1);
|
||||
let c: bool = @get(state, 2);
|
||||
return cell_merger(a, b, c);
|
||||
end;
|
||||
| 1 -> do
|
||||
let a: bool = @get(state, 0);
|
||||
let b: bool = @get(state, 1);
|
||||
let c: bool = @get(state, 2);
|
||||
return cell_merger(a, b, c);
|
||||
end;
|
||||
| 2 -> do
|
||||
let a: bool = @get(state, 1);
|
||||
let b: bool = @get(state, 2);
|
||||
let c: bool = @get(state, 3);
|
||||
return cell_merger(a, b, c);
|
||||
end;
|
||||
| 3 -> do
|
||||
let a: bool = @get(state, 2);
|
||||
let b: bool = @get(state, 3);
|
||||
let c: bool = @get(state, 4);
|
||||
return cell_merger(a, b, c);
|
||||
end;
|
||||
| 4 -> do
|
||||
let a: bool = @get(state, 3);
|
||||
let b: bool = @get(state, 4);
|
||||
let c: bool = @get(state, 5);
|
||||
return cell_merger(a, b, c);
|
||||
end;
|
||||
| 5 -> do
|
||||
return true;
|
||||
end;
|
||||
| else return false;
|
||||
end;
|
||||
end;
|
||||
|
||||
fun iter (state: vec_bool) (for: int) (curr: int): void = do
|
||||
if curr == for then
|
||||
@write("");
|
||||
else
|
||||
do
|
||||
let next_state: vec_bool = [
|
||||
next(state, 0),
|
||||
next(state, 1),
|
||||
next(state, 2),
|
||||
next(state, 3),
|
||||
next(state, 4),
|
||||
next(state, 5)
|
||||
];
|
||||
|
||||
print_vec(next_state, 6, 0);
|
||||
@write("\n");
|
||||
iter(next_state, for, curr + 1);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
fun main: void = do
|
||||
let vec: vec_bool = [false, false, false, false, false, true];
|
||||
print_vec(vec, 6, 0);
|
||||
@write("\n");
|
||||
|
||||
iter(vec, 20, 0);
|
||||
end;
|
Loading…
Reference in a new issue