[fine] Garbage Compile
This commit is contained in:
parent
8d09076586
commit
6d2fd446ee
3 changed files with 113 additions and 38 deletions
93
fine/src/compiler.rs
Normal file
93
fine/src/compiler.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use crate::{
|
||||
parser::{Tree, TreeKind, TreeRef},
|
||||
semantics::{Semantics, Type},
|
||||
tokens::TokenKind,
|
||||
};
|
||||
|
||||
// TODO: If I were cool this would by actual bytecode.
|
||||
// But I'm not cool.
|
||||
pub enum Instruction {
|
||||
Panic,
|
||||
PushFloat(f64),
|
||||
PushString(usize),
|
||||
PushTrue,
|
||||
PushFalse,
|
||||
}
|
||||
|
||||
pub struct Function {
|
||||
instructions: Vec<Instruction>,
|
||||
strings: Vec<String>,
|
||||
}
|
||||
|
||||
pub fn compile_expression(code: &mut Function, semantics: &Semantics, t: TreeRef) {
|
||||
let tree = &semantics.tree()[t];
|
||||
match tree.kind {
|
||||
TreeKind::Error => code.instructions.push(Instruction::Panic),
|
||||
TreeKind::LiteralExpression => compile_literal(code, semantics, t, tree),
|
||||
TreeKind::GroupingExpression => compile_grouping(code, semantics, tree),
|
||||
TreeKind::UnaryExpression => todo!(),
|
||||
TreeKind::ConditionalExpression => todo!(),
|
||||
TreeKind::BinaryExpression => todo!(),
|
||||
TreeKind::Identifier => todo!(),
|
||||
TreeKind::CallExpression => todo!(),
|
||||
TreeKind::Block => todo!(),
|
||||
_ => {
|
||||
semantics.internal_compiler_error(Some(t), "tree is not an expression, cannot compile")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_literal(code: &mut Function, semantics: &Semantics, t: TreeRef, tr: &Tree) {
|
||||
let Some(tok) = tr.nth_token(0) else {
|
||||
code.instructions.push(Instruction::Panic);
|
||||
return;
|
||||
};
|
||||
match semantics.type_of(t) {
|
||||
Type::F64 => code
|
||||
.instructions
|
||||
.push(Instruction::PushFloat(tok.as_str().parse().unwrap())),
|
||||
Type::Bool => code.instructions.push(if tok.kind == TokenKind::True {
|
||||
Instruction::PushTrue
|
||||
} else {
|
||||
Instruction::PushFalse
|
||||
}),
|
||||
Type::String => {
|
||||
let index = code.strings.len();
|
||||
|
||||
// TODO: Interpret string here make good!
|
||||
let mut result = String::new();
|
||||
let mut input = tok.as_str().chars();
|
||||
while let Some(ch) = input.next() {
|
||||
if ch == '\\' {
|
||||
if let Some(ch) = input.next() {
|
||||
match ch {
|
||||
'n' => result.push('\n'),
|
||||
'r' => result.push('\r'),
|
||||
't' => result.push('\t'),
|
||||
_ => result.push(ch),
|
||||
}
|
||||
} else {
|
||||
result.push(ch)
|
||||
}
|
||||
} else {
|
||||
result.push(ch)
|
||||
}
|
||||
}
|
||||
code.strings.push(result);
|
||||
|
||||
code.instructions.push(Instruction::PushString(index))
|
||||
}
|
||||
Type::Error => code.instructions.push(Instruction::Panic),
|
||||
_ => panic!("unsupported literal type: {t:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_grouping(code: &mut Function, semantics: &Semantics, t: &Tree) {
|
||||
if let Some(t) = t.nth_tree(1) {
|
||||
compile_expression(code, semantics, t)
|
||||
} else {
|
||||
code.instructions.push(Instruction::Panic);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile_statement(code: &mut Function, semantics: &Semantics, t: TreeRef) {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue