Add Empty and Comment options to FnLine

This commit is contained in:
Andrew Morris
2023-06-22 15:54:00 +10:00
parent 2edab0ce63
commit 6e1be5a929
8 changed files with 127 additions and 88 deletions

View File

@@ -106,7 +106,7 @@ impl std::fmt::Display for Pointer {
pub struct Function {
pub is_generator: bool,
pub parameters: Vec<Register>,
pub body: Vec<InstructionOrLabel>,
pub body: Vec<FnLine>,
}
impl std::fmt::Display for Function {
@@ -123,14 +123,12 @@ impl std::fmt::Display for Function {
write!(f, "{}", parameter)?;
}
write!(f, ") {{\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)?;
}
for fn_line in &self.body {
match fn_line {
FnLine::Instruction(instruction) => write!(f, " {}\n", instruction)?,
FnLine::Label(label) => write!(f, "{}\n", label)?,
FnLine::Empty => write!(f, "\n")?,
FnLine::Comment(message) => write!(f, " // {}\n", message)?,
}
}
write!(f, "}}")
@@ -244,20 +242,26 @@ impl std::fmt::Display for Register {
}
#[derive(Debug, Clone)]
pub enum InstructionOrLabel {
pub enum FnLine {
Instruction(Instruction),
Label(Label),
Empty,
Comment(String),
}
impl std::fmt::Display for InstructionOrLabel {
impl std::fmt::Display for FnLine {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
InstructionOrLabel::Instruction(instruction) => {
FnLine::Instruction(instruction) => {
write!(f, "{}", instruction)
}
InstructionOrLabel::Label(label) => {
FnLine::Label(label) => {
write!(f, "{}", label)
}
FnLine::Empty => Ok(()),
FnLine::Comment(message) => {
write!(f, "// {}", message)
}
}
}
}
@@ -653,21 +657,19 @@ impl std::fmt::Display for Value {
#[derive(Debug, Clone)]
pub struct Lazy {
pub body: Vec<InstructionOrLabel>,
pub body: Vec<FnLine>,
}
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)?;
}
for fn_line in &self.body {
match fn_line {
FnLine::Instruction(instruction) => write!(f, " {}\n", instruction)?,
FnLine::Label(label) => write!(f, "{}\n", label)?,
FnLine::Empty => write!(f, "\n")?,
FnLine::Comment(message) => write!(f, " // {}\n", message)?,
}
}

View File

@@ -8,8 +8,8 @@ use num_bigint::{BigInt, Sign};
use valuescript_common::BuiltinName;
use crate::asm::{
Array, Builtin, Class, Definition, DefinitionContent, Function, Instruction, InstructionOrLabel,
Label, LabelRef, Lazy, Module, Object, Pointer, Register, Value,
Array, Builtin, Class, Definition, DefinitionContent, FnLine, Function, Instruction, Label,
LabelRef, Lazy, Module, Object, Pointer, Register, Value,
};
pub fn assemble(module: &Module) -> Vec<u8> {
@@ -94,14 +94,15 @@ impl Assembler {
self.lookup_register(parameter);
}
for instruction_or_label in &function.body {
match instruction_or_label {
InstructionOrLabel::Instruction(instruction) => {
for fn_line in &function.body {
match fn_line {
FnLine::Instruction(instruction) => {
self.instruction(instruction);
}
InstructionOrLabel::Label(label) => {
FnLine::Label(label) => {
self.label(label);
}
FnLine::Empty | FnLine::Comment(..) => {}
}
}
@@ -121,14 +122,15 @@ impl Assembler {
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) => {
for fn_line in &lazy.body {
match fn_line {
FnLine::Instruction(instruction) => {
self.instruction(instruction);
}
InstructionOrLabel::Label(label) => {
FnLine::Label(label) => {
self.label(label);
}
FnLine::Empty | FnLine::Comment(..) => {}
}
}

View File

@@ -5,8 +5,8 @@ use num_bigint::BigInt;
use valuescript_common::{InstructionByte, BUILTIN_NAMES};
use crate::asm::{
Array, Builtin, Class, Definition, DefinitionContent, Function, Instruction, InstructionOrLabel,
Label, LabelRef, Module, Object, Pointer, Register, Value,
Array, Builtin, Class, Definition, DefinitionContent, FnLine, Function, Instruction, Label,
LabelRef, Module, Object, Pointer, Register, Value,
};
pub struct AssemblyParser<'a> {
@@ -152,6 +152,28 @@ impl<'a> AssemblyParser<'a> {
}
}
fn parse_line(&mut self) {
loop {
match self.pos.next() {
Some('\n') => return,
_ => {}
}
}
}
fn parse_optional_spaces(&mut self) {
loop {
match self.pos.peek() {
Some(' ') => {}
_ => {
return;
}
}
self.pos.next();
}
}
fn assemble_definition(&mut self) -> Definition {
self.parse_exact("@");
let def_name = self.parse_identifier();
@@ -236,8 +258,12 @@ impl<'a> AssemblyParser<'a> {
for (word, instruction) in instruction_word_map {
if self.test_instruction_word(word) {
advance_chars(&mut self.pos, word.len() + 1);
self.parse_optional_whitespace();
advance_chars(&mut self.pos, word.len());
match self.pos.peek() {
Some('\n') | None | Some(' ') => {}
_ => panic!("Unexpected non-whitespace character after instruction word"),
}
self.parse_optional_spaces();
return instruction;
}
}
@@ -433,15 +459,22 @@ impl<'a> AssemblyParser<'a> {
self.parse_optional_whitespace();
self.parse_exact("{");
self.parse_line();
loop {
self.parse_optional_whitespace();
self.parse_optional_spaces();
let c = *self
.pos
.peek()
.expect("Expected instruction, label, or end of function");
if c == '\n' {
self.pos.next();
function.body.push(FnLine::Empty);
continue;
}
if c == '}' {
self.pos.next();
break;
@@ -450,27 +483,30 @@ impl<'a> AssemblyParser<'a> {
if c == '/' {
self.parse_exact("//");
loop {
let c = self.pos.next();
let mut msg = String::new();
if c == None || c == Some('\n') {
break;
loop {
match self.pos.next() {
Some('\n') | None => break,
Some(c) => msg.push(c),
}
}
function.body.push(FnLine::Comment(msg.trim().to_string()));
continue;
}
let optional_label = self.test_label();
if optional_label.is_some() {
function.body.push(InstructionOrLabel::Label(
self.assemble_label(optional_label.unwrap()),
));
function
.body
.push(FnLine::Label(self.assemble_label(optional_label.unwrap())));
} else {
function
.body
.push(InstructionOrLabel::Instruction(self.assemble_instruction()));
.push(FnLine::Instruction(self.assemble_instruction()));
}
}
@@ -503,7 +539,7 @@ impl<'a> AssemblyParser<'a> {
let instr = self.parse_instruction_word();
match instr {
let res = match instr {
End => Instruction::End,
Mov => Instruction::Mov(self.assemble_value(), self.assemble_register()),
OpInc => Instruction::OpInc(self.assemble_register()),
@@ -709,7 +745,11 @@ impl<'a> AssemblyParser<'a> {
Cat => Instruction::Cat(self.assemble_value(), self.assemble_register()),
Yield => Instruction::Yield(self.assemble_value(), self.assemble_register()),
YieldStar => Instruction::Yield(self.assemble_value(), self.assemble_register()),
}
};
self.parse_line();
res
}
pub fn assemble_value(&mut self) -> Value {
@@ -803,7 +843,6 @@ impl<'a> AssemblyParser<'a> {
}
if next == "]" {
self.parse_optional_whitespace();
break array;
}
@@ -852,9 +891,7 @@ impl<'a> AssemblyParser<'a> {
}
fn assemble_label(&mut self, name: String) -> Label {
self.parse_optional_whitespace();
advance_chars(&mut self.pos, name.len() + 1);
self.parse_line();
Label { name }
}

View File

@@ -7,8 +7,8 @@ use std::rc::Rc;
use swc_common::Spanned;
use crate::asm::{
Array, Builtin, Definition, DefinitionContent, Function, Instruction, InstructionOrLabel, Label,
Pointer, Register, Value,
Array, Builtin, Definition, DefinitionContent, FnLine, Function, Instruction, Label, Pointer,
Register, Value,
};
use crate::diagnostic::{Diagnostic, DiagnosticLevel};
use crate::expression_compiler::CompiledExpression;
@@ -22,11 +22,7 @@ use crate::scope_analysis::{fn_to_owner_id, Name, ScopeAnalysis};
pub enum Functionish {
Fn(Option<swc_ecma_ast::Ident>, swc_ecma_ast::Function),
Arrow(swc_ecma_ast::ArrowExpr),
Constructor(
Vec<InstructionOrLabel>,
swc_common::Span,
swc_ecma_ast::Constructor,
),
Constructor(Vec<FnLine>, swc_common::Span, swc_ecma_ast::Constructor),
}
impl Spanned for Functionish {
@@ -121,14 +117,12 @@ impl FunctionCompiler {
}
pub fn push_raw(&mut self, instruction: Instruction) {
self
.current
.body
.push(InstructionOrLabel::Instruction(instruction));
self.current.body.push(FnLine::Instruction(instruction));
}
pub fn label(&mut self, label: Label) {
self.current.body.push(InstructionOrLabel::Label(label));
self.current.body.push(FnLine::Empty);
self.current.body.push(FnLine::Label(label));
}
pub fn lookup(&mut self, ident: &swc_ecma_ast::Ident) -> Option<&Name> {
@@ -330,10 +324,7 @@ impl FunctionCompiler {
};
if let Some(end_label) = self.end_label.as_ref() {
self
.current
.body
.push(InstructionOrLabel::Label(end_label.clone()));
self.current.body.push(FnLine::Label(end_label.clone()));
self.end_label = None;
self.is_returning_register = None;

View File

@@ -1,4 +1,4 @@
use crate::asm::{Definition, DefinitionContent, Instruction, InstructionOrLabel, Pointer, Value};
use crate::asm::{Definition, DefinitionContent, FnLine, Instruction, Pointer, Value};
pub struct ImportPattern {
pub pointer: Pointer,
@@ -24,7 +24,7 @@ impl ImportPattern {
}
let first_instruction = match lazy.body.first() {
Some(InstructionOrLabel::Instruction(instruction)) => instruction,
Some(FnLine::Instruction(instruction)) => instruction,
_ => return None,
};
@@ -59,7 +59,7 @@ impl ImportPattern {
}
let second_instruction = match second_instruction_opt {
Some(InstructionOrLabel::Instruction(instruction)) => instruction,
Some(FnLine::Instruction(instruction)) => instruction,
Some(_) => return None,
_ => {
return Some(ImportPattern {

View File

@@ -1,7 +1,7 @@
use std::collections::{HashMap, HashSet};
use crate::asm::{
Array, Definition, DefinitionContent, Instruction, InstructionOrLabel, Object, Pointer, Value,
Array, Definition, DefinitionContent, FnLine, Instruction, Object, Pointer, Value,
};
use crate::gather_modules::PathAndModule;
use crate::import_pattern::{ImportKind, ImportPattern};
@@ -298,13 +298,13 @@ where
};
}
fn body(&mut self, owner: &Pointer, body: &mut Vec<InstructionOrLabel>) {
for instruction_or_label in body {
match instruction_or_label {
InstructionOrLabel::Instruction(instruction) => {
fn body(&mut self, owner: &Pointer, body: &mut Vec<FnLine>) {
for fn_line in body {
match fn_line {
FnLine::Instruction(instruction) => {
self.instruction(owner, instruction);
}
InstructionOrLabel::Label(_) => {}
FnLine::Label(..) | FnLine::Empty | FnLine::Comment(..) => {}
}
}
}
@@ -325,7 +325,7 @@ fn resolve_and_rewrite_import_patterns(path_and_module: &mut PathAndModule) -> V
};
let first_instruction = match lazy.body.first_mut() {
Some(InstructionOrLabel::Instruction(instruction)) => instruction,
Some(FnLine::Instruction(instruction)) => instruction,
_ => panic!("Inconsistent with import pattern"),
};

View File

@@ -8,8 +8,8 @@ use swc_ecma_ast::EsVersion;
use swc_ecma_parser::{Syntax, TsConfig};
use crate::asm::{
Class, Definition, DefinitionContent, Function, Instruction, InstructionOrLabel, Lazy, Module,
Object, Pointer, Register, Value,
Class, Definition, DefinitionContent, FnLine, Function, Instruction, Lazy, Module, Object,
Pointer, Register, Value,
};
use crate::diagnostic::{Diagnostic, DiagnosticLevel};
use crate::expression_compiler::{CompiledExpression, ExpressionCompiler};
@@ -406,16 +406,16 @@ impl ModuleCompiler {
pointer: defn.clone(),
content: DefinitionContent::Lazy(Lazy {
body: match orig_name.sym.to_string() == "default" {
true => vec![InstructionOrLabel::Instruction(Instruction::Import(
true => vec![FnLine::Instruction(Instruction::Import(
Value::String(src.value.to_string()),
Register::return_(),
))],
false => vec![
InstructionOrLabel::Instruction(Instruction::ImportStar(
FnLine::Instruction(Instruction::ImportStar(
Value::String(src.value.to_string()),
Register::return_(),
)),
InstructionOrLabel::Instruction(Instruction::Sub(
FnLine::Instruction(Instruction::Sub(
Value::Register(Register::return_()),
Value::String(orig_name.sym.to_string()),
Register::return_(),
@@ -499,7 +499,7 @@ impl ModuleCompiler {
self.module.definitions.push(Definition {
pointer: defn.clone(),
content: DefinitionContent::Lazy(Lazy {
body: vec![InstructionOrLabel::Instruction(Instruction::ImportStar(
body: vec![FnLine::Instruction(Instruction::ImportStar(
Value::String(src),
Register::return_(),
))],
@@ -572,11 +572,11 @@ impl ModuleCompiler {
pointer,
content: DefinitionContent::Lazy(Lazy {
body: vec![
InstructionOrLabel::Instruction(Instruction::ImportStar(
FnLine::Instruction(Instruction::ImportStar(
Value::String(import_path.clone()),
Register::return_(),
)),
InstructionOrLabel::Instruction(Instruction::Sub(
FnLine::Instruction(Instruction::Sub(
Value::Register(Register::return_()),
Value::String(external_name),
Register::return_(),
@@ -607,7 +607,7 @@ impl ModuleCompiler {
self.module.definitions.push(Definition {
pointer,
content: DefinitionContent::Lazy(Lazy {
body: vec![InstructionOrLabel::Instruction(Instruction::Import(
body: vec![FnLine::Instruction(Instruction::Import(
Value::String(import_path.clone()),
Register::return_(),
))],
@@ -636,7 +636,7 @@ impl ModuleCompiler {
self.module.definitions.push(Definition {
pointer,
content: DefinitionContent::Lazy(Lazy {
body: vec![InstructionOrLabel::Instruction(Instruction::ImportStar(
body: vec![FnLine::Instruction(Instruction::ImportStar(
Value::String(import_path.clone()),
Register::return_(),
))],
@@ -738,7 +738,7 @@ impl ModuleCompiler {
}
}
let mut member_initializers_assembly = Vec::<InstructionOrLabel>::new();
let mut member_initializers_assembly = Vec::<FnLine>::new();
member_initializers_assembly.append(&mut member_initializers_fnc.current.body);
// Include any other definitions that were created by the member initializers