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

5 changed files with 176 additions and 5 deletions

View file

@ -64,6 +64,7 @@ impl Codegen {
"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('"')) },
"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!() },
}

View file

@ -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!() }
}
}

View file

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

View file

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