[fine] While loops, nothing
This commit is contained in:
parent
1cc5ce6ca9
commit
ac3c158a81
7 changed files with 166 additions and 48 deletions
|
|
@ -15,18 +15,23 @@ pub enum Instruction {
|
|||
|
||||
BoolNot,
|
||||
Call(usize),
|
||||
CompareBool,
|
||||
CompareFloat,
|
||||
CompareString,
|
||||
Discard,
|
||||
Dup,
|
||||
EqBool,
|
||||
EqFloat,
|
||||
EqString,
|
||||
FloatAdd,
|
||||
FloatDivide,
|
||||
FloatMultiply,
|
||||
FloatSubtract,
|
||||
GreaterFloat,
|
||||
GreaterString,
|
||||
IsClass(i64),
|
||||
Jump(usize),
|
||||
JumpFalse(usize),
|
||||
JumpTrue(usize), // TODO: Only one of these, and use BoolNot?
|
||||
LessFloat,
|
||||
LessString,
|
||||
LoadArgument(usize),
|
||||
LoadExternFunction(usize), // NOTE: FUNKY, might want to indirect this index.
|
||||
LoadFunction(usize),
|
||||
|
|
@ -36,6 +41,7 @@ pub enum Instruction {
|
|||
NewObject(usize),
|
||||
PushFalse,
|
||||
PushFloat(f64),
|
||||
PushInt(i64),
|
||||
PushNothing,
|
||||
PushString(usize),
|
||||
PushTrue,
|
||||
|
|
@ -44,9 +50,6 @@ pub enum Instruction {
|
|||
StoreLocal(usize),
|
||||
StoreModule(usize),
|
||||
StringAdd,
|
||||
|
||||
IsClass(i64),
|
||||
PushInt(i64),
|
||||
}
|
||||
|
||||
pub enum Export {
|
||||
|
|
@ -411,7 +414,8 @@ where
|
|||
}
|
||||
|
||||
fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR {
|
||||
match tr.nth_token(1)?.kind {
|
||||
let op = tr.nth_token(1)?;
|
||||
match op.kind {
|
||||
TokenKind::Plus => compile_simple_binary_expression(c, tr, |_, t| match t {
|
||||
Type::F64 => Instruction::FloatAdd,
|
||||
Type::String => Instruction::StringAdd,
|
||||
|
|
@ -426,6 +430,36 @@ fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR {
|
|||
TokenKind::Slash => {
|
||||
compile_simple_binary_expression(c, tr, |_, _| Instruction::FloatDivide)
|
||||
}
|
||||
|
||||
TokenKind::Less => compile_simple_binary_expression(c, tr, |_, t| match t {
|
||||
Type::F64 => Instruction::LessFloat,
|
||||
Type::String => Instruction::LessString,
|
||||
_ => inst_panic!("panic less {}", t),
|
||||
}),
|
||||
TokenKind::LessEqual => {
|
||||
compile_simple_binary_expression(c, tr, |_, t| match t {
|
||||
Type::F64 => Instruction::GreaterFloat,
|
||||
Type::String => Instruction::GreaterString,
|
||||
_ => inst_panic!("panic less equal {}", t),
|
||||
});
|
||||
c.push(Instruction::BoolNot);
|
||||
OK
|
||||
}
|
||||
TokenKind::Greater => compile_simple_binary_expression(c, tr, |_, t| match t {
|
||||
Type::F64 => Instruction::GreaterFloat,
|
||||
Type::String => Instruction::GreaterString,
|
||||
_ => inst_panic!("panic greater {}", t),
|
||||
}),
|
||||
TokenKind::GreaterEqual => {
|
||||
compile_simple_binary_expression(c, tr, |_, t| match t {
|
||||
Type::F64 => Instruction::LessFloat,
|
||||
Type::String => Instruction::LessString,
|
||||
_ => inst_panic!("panic greater equal {}", t),
|
||||
});
|
||||
c.push(Instruction::BoolNot);
|
||||
OK
|
||||
}
|
||||
|
||||
TokenKind::And => {
|
||||
// Compile the left hand side, it leaves a bool on the stack
|
||||
compile_expression(c, tr.nth_tree(0)?);
|
||||
|
|
@ -486,9 +520,9 @@ fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR {
|
|||
Instruction::PushTrue
|
||||
} else {
|
||||
match arg_type {
|
||||
Type::F64 => Instruction::CompareFloat,
|
||||
Type::String => Instruction::CompareString,
|
||||
Type::Bool => Instruction::CompareBool, // ?
|
||||
Type::F64 => Instruction::EqFloat,
|
||||
Type::String => Instruction::EqString,
|
||||
Type::Bool => Instruction::EqBool, // ?
|
||||
_ => inst_panic!("panic comparing {}", arg_type),
|
||||
}
|
||||
}
|
||||
|
|
@ -545,7 +579,7 @@ fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR {
|
|||
}
|
||||
OK
|
||||
}
|
||||
_ => ice!(c, t, "Unsupported binary expression"),
|
||||
_ => ice!(c, t, "Unsupported binary expression '{op}'"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -898,13 +932,15 @@ fn compile_self_reference(c: &mut Compiler) -> CR {
|
|||
fn compile_statement(c: &mut Compiler, t: TreeRef, gen_value: bool) {
|
||||
let tree = &c.semantics.tree()[t];
|
||||
let cr = match tree.kind {
|
||||
TreeKind::FunctionDecl => compile_function_declaration(c, t, tree, gen_value),
|
||||
TreeKind::ClassDecl => compile_class_declaration(c, t, tree, gen_value),
|
||||
TreeKind::LetStatement => compile_let_statement(c, t, tree, gen_value),
|
||||
TreeKind::ExpressionStatement => compile_expression_statement(c, tree, gen_value),
|
||||
TreeKind::IfStatement => compile_if_statement(c, tree, gen_value),
|
||||
TreeKind::Block => compile_block_statement(c, t, gen_value),
|
||||
_ => ice!(c, t, "unsupported tree kind {:?}", tree.kind),
|
||||
TreeKind::ClassDecl => compile_class_declaration(c, t, tree, gen_value),
|
||||
TreeKind::ExpressionStatement => compile_expression_statement(c, tree, gen_value),
|
||||
TreeKind::FunctionDecl => compile_function_declaration(c, t, tree, gen_value),
|
||||
TreeKind::IfStatement => compile_if_statement(c, tree, gen_value),
|
||||
TreeKind::LetStatement => compile_let_statement(c, t, tree, gen_value),
|
||||
TreeKind::WhileStatement => compile_while_statement(c, tree, gen_value),
|
||||
|
||||
_ => ice!(c, t, "unsupported statement tree kind {:?}", tree.kind),
|
||||
};
|
||||
if matches!(cr, None) {
|
||||
c.push(inst_panic!("stat {:?}", tree));
|
||||
|
|
@ -1076,3 +1112,20 @@ fn compile_block_statement(c: &mut Compiler, t: TreeRef, gen_value: bool) -> CR
|
|||
|
||||
OK
|
||||
}
|
||||
|
||||
fn compile_while_statement(c: &mut Compiler, tree: &Tree, gen_value: bool) -> CR {
|
||||
let start_index = c.function.instructions.len();
|
||||
compile_expression(c, tree.nth_tree(1)?);
|
||||
|
||||
let jump_end_index = c.push(Instruction::JumpFalse(0));
|
||||
|
||||
compile_block_statement(c, tree.nth_tree(2)?, false);
|
||||
c.push(Instruction::Jump(start_index));
|
||||
|
||||
c.patch(jump_end_index, |i| Instruction::JumpFalse(i));
|
||||
if gen_value {
|
||||
c.push(Instruction::PushNothing);
|
||||
}
|
||||
|
||||
OK
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue