mirror of
https://github.com/azur1s/bobbylisp.git
synced 2024-10-16 02:37:40 -05:00
rule 110 & vector type
This commit is contained in:
parent
990ee95372
commit
1ce9b74190
|
@ -64,6 +64,7 @@ impl Codegen {
|
||||||
"read" => { format!("read({}){}\n" , self.gen_ir(&args[0], 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!()) }
|
"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
|
_ => 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)]
|
#[allow(unreachable_patterns)]
|
||||||
_ => { dbg!(ir); todo!() },
|
_ => { dbg!(ir); todo!() },
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use parser::Expr;
|
use parser::Expr;
|
||||||
|
|
||||||
const INTRINSICS: [&str; 5] = [
|
const INTRINSICS: [&str; 6] = [
|
||||||
"write",
|
"write",
|
||||||
"read",
|
"read",
|
||||||
"write_file",
|
"write_file",
|
||||||
"read_file",
|
"read_file",
|
||||||
"emit",
|
"emit",
|
||||||
|
"get",
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -47,7 +48,10 @@ pub enum IRKind {
|
||||||
Case { cond: Box<Self>, cases: Vec<(Box<Self>, Box<Self>)>, default: Box<Self> },
|
Case { cond: Box<Self>, cases: Vec<(Box<Self>, Box<Self>)>, default: Box<Self> },
|
||||||
Unary { op: String, right: Box<Self> },
|
Unary { op: String, right: Box<Self> },
|
||||||
Binary { op: String, left: Box<Self>, right: Box<Self> },
|
Binary { op: String, left: Box<Self>, right: Box<Self> },
|
||||||
|
|
||||||
Value { value: Value },
|
Value { value: Value },
|
||||||
|
Vector { values: Vec<Self> },
|
||||||
|
|
||||||
Return { value: Box<Self> },
|
Return { value: Box<Self> },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +106,9 @@ impl std::fmt::Display for IRKind {
|
||||||
IRKind::Value { ref value } => {
|
IRKind::Value { ref value } => {
|
||||||
write!(f, "{}", value)
|
write!(f, "{}", value)
|
||||||
},
|
},
|
||||||
|
IRKind::Vector { ref values } => {
|
||||||
|
write!(f, "[{}]", values.iter().map(|expr| expr.to_string()).collect::<Vec<_>>().join(" "))
|
||||||
|
},
|
||||||
IRKind::Return { ref value } => {
|
IRKind::Return { ref value } => {
|
||||||
write!(f, "(return {})", 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::Boolean(value) => (Some(IRKind::Value { value: Value::Boolean(*value) }), None),
|
||||||
Expr::String(value) => (Some(IRKind::Value { value: Value::String(value.clone()) }), 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::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
|
// Probably will never happen because it is catched in parser
|
||||||
Expr::Hole(start, end) => (None, Some(LoweringError {
|
Expr::Hole(start, end) => (None, Some(LoweringError {
|
||||||
span: *start..*end,
|
span: *start..*end,
|
||||||
|
@ -418,6 +437,10 @@ fn gen_type_hint(type_hint: &str) -> String {
|
||||||
"bool" => "boolean".to_string(),
|
"bool" => "boolean".to_string(),
|
||||||
"string" => "string".to_string(),
|
"string" => "string".to_string(),
|
||||||
"void" => "void".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!() }
|
_ => { dbg!(type_hint); todo!() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ pub enum Token {
|
||||||
Dot, Comma,
|
Dot, Comma,
|
||||||
Colon, SemiColon,
|
Colon, SemiColon,
|
||||||
OpenParen, CloseParen,
|
OpenParen, CloseParen,
|
||||||
|
OpenBracket, CloseBracket,
|
||||||
At,
|
At,
|
||||||
Hole,
|
Hole,
|
||||||
}
|
}
|
||||||
|
@ -69,8 +70,12 @@ impl std::fmt::Display for Token {
|
||||||
Token::Comma => write!(f, ","),
|
Token::Comma => write!(f, ","),
|
||||||
Token::Colon => write!(f, ":"),
|
Token::Colon => write!(f, ":"),
|
||||||
Token::SemiColon => write!(f, ";"),
|
Token::SemiColon => write!(f, ";"),
|
||||||
|
|
||||||
Token::OpenParen => write!(f, "("),
|
Token::OpenParen => write!(f, "("),
|
||||||
Token::CloseParen => write!(f, ")"),
|
Token::CloseParen => write!(f, ")"),
|
||||||
|
Token::OpenBracket => write!(f, "["),
|
||||||
|
Token::CloseBracket => write!(f, "]"),
|
||||||
|
|
||||||
Token::At => write!(f, "@"),
|
Token::At => write!(f, "@"),
|
||||||
Token::Hole => 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::SemiColon),
|
||||||
just('(').to(Token::OpenParen),
|
just('(').to(Token::OpenParen),
|
||||||
just(')').to(Token::CloseParen),
|
just(')').to(Token::CloseParen),
|
||||||
|
just('[').to(Token::OpenBracket),
|
||||||
|
just(']').to(Token::CloseBracket),
|
||||||
just('@').to(Token::At),
|
just('@').to(Token::At),
|
||||||
just('_').to(Token::Hole),
|
just('_').to(Token::Hole),
|
||||||
));
|
));
|
||||||
|
|
|
@ -8,6 +8,8 @@ pub enum Expr {
|
||||||
Int(i64), Float(f64), Boolean(bool),
|
Int(i64), Float(f64), Boolean(bool),
|
||||||
String(String), Identifier(String),
|
String(String), Identifier(String),
|
||||||
|
|
||||||
|
Vector(Vec<Spanned<Self>>),
|
||||||
|
|
||||||
Unary { op: String, rhs: Box<Spanned<Self>> },
|
Unary { op: String, rhs: Box<Spanned<Self>> },
|
||||||
Binary { lhs: Box<Spanned<Self>>, 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>>> },
|
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))
|
.separated_by(just(Token::Comma))
|
||||||
.allow_trailing();
|
.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
|
let atom = literal
|
||||||
.or(identifier.map(|(s, span)| (Expr::Identifier(s), span)))
|
.or(identifier.map(|(s, span)| (Expr::Identifier(s), span)))
|
||||||
// .or(
|
.or(vector)
|
||||||
// expr.clone()
|
|
||||||
// .delimited_by(just(Token::OpenParen), just(Token::CloseParen)))
|
|
||||||
.labelled("atom");
|
.labelled("atom");
|
||||||
|
|
||||||
let call = atom.clone()
|
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