From 53d64addb99d1bfa38d196e7383b1350ddb957be Mon Sep 17 00:00:00 2001 From: Andrew Morris Date: Wed, 8 Mar 2023 09:40:32 +1100 Subject: [PATCH] Add Lazy to asm.rs --- valuescript_compiler/src/asm.rs | 28 +++++++++++++++++++++++ valuescript_compiler/src/assembler.rs | 33 ++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/valuescript_compiler/src/asm.rs b/valuescript_compiler/src/asm.rs index 59bca89..b2996a9 100644 --- a/valuescript_compiler/src/asm.rs +++ b/valuescript_compiler/src/asm.rs @@ -64,6 +64,7 @@ pub enum DefinitionContent { Function(Function), Class(Class), Value(Value), + Lazy(Lazy), } impl std::fmt::Display for DefinitionContent { @@ -78,6 +79,9 @@ impl std::fmt::Display for DefinitionContent { DefinitionContent::Value(value) => { write!(f, "{}", value) } + DefinitionContent::Lazy(lazy) => { + write!(f, "{}", lazy) + } } } } @@ -499,6 +503,30 @@ impl std::fmt::Display for Value { } } +#[derive(Debug)] +pub struct Lazy { + pub body: Vec, +} + +impl std::fmt::Display for Lazy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "lazy {{\n")?; + + for instruction_or_label in &self.body { + match instruction_or_label { + InstructionOrLabel::Instruction(instruction) => { + write!(f, " {}\n", instruction)?; + } + InstructionOrLabel::Label(label) => { + write!(f, "{}\n", label)?; + } + } + } + + write!(f, "}}") + } +} + #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Builtin { pub name: String, diff --git a/valuescript_compiler/src/assembler.rs b/valuescript_compiler/src/assembler.rs index 48a63e3..ea3dcd6 100644 --- a/valuescript_compiler/src/assembler.rs +++ b/valuescript_compiler/src/assembler.rs @@ -5,7 +5,7 @@ use std::{ use crate::asm::{ Array, Builtin, Class, Definition, DefinitionContent, Function, Instruction, InstructionOrLabel, - Label, LabelRef, Module, Object, Pointer, Register, Value, + Label, LabelRef, Lazy, Module, Object, Pointer, Register, Value, }; pub fn assemble(module: &Module) -> Rc> { @@ -58,6 +58,9 @@ impl Assembler { DefinitionContent::Value(value) => { self.value(value); } + DefinitionContent::Lazy(lazy) => { + self.lazy(lazy); + } } } @@ -105,6 +108,33 @@ impl Assembler { self.fn_data.labels_map.resolve(&mut self.output); } + fn lazy(&mut self, lazy: &Lazy) { + self.output.push(ValueType::Lazy as u8); + + self.fn_data = Default::default(); + self.fn_data.register_count_pos = self.output.len(); + self.output.push(0xff); // Placeholder for register count + + for instruction_or_label in &lazy.body { + match instruction_or_label { + InstructionOrLabel::Instruction(instruction) => { + self.instruction(instruction); + } + InstructionOrLabel::Label(label) => { + self.label(label); + } + } + } + + self.output.push(Instruction::End.byte()); + + // TODO: Handle >255 registers + // +3: return, this, ignore + self.output[self.fn_data.register_count_pos] = (self.fn_data.register_map.len() + 3) as u8; + + self.fn_data.labels_map.resolve(&mut self.output); + } + fn class(&mut self, class: &Class) { self.output.push(ValueType::Class as u8); self.value(&class.constructor); @@ -344,6 +374,7 @@ enum ValueType { // External = 0x0f, Builtin = 0x10, Class = 0x11, + Lazy = 0x12, } #[derive(Hash, PartialEq, Eq, Clone)]