summaryrefslogtreecommitdiff
path: root/src/stages/bytecode.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/stages/bytecode.rs')
-rw-r--r--src/stages/bytecode.rs24
1 files changed, 8 insertions, 16 deletions
diff --git a/src/stages/bytecode.rs b/src/stages/bytecode.rs
index 6878c42..02cc739 100644
--- a/src/stages/bytecode.rs
+++ b/src/stages/bytecode.rs
@@ -1,6 +1,6 @@
use crate::*;
-use std::collections::HashMap;
+use indexmap::IndexMap;
/// Doesn't truncate trailing null bytes.
@@ -14,22 +14,16 @@ pub fn generate_bytecode(semantic: &Program) -> Result<AssembledProgram, Vec<Tra
let address = information.address;
symbols.push(AssembledSymbol { name, address, source });
}
-
match generator.errors.is_empty() {
- true => Ok(
- AssembledProgram {
- bytecode: generator.bytecode,
- symbols,
- }
- ),
+ true => Ok(AssembledProgram { bytecode: generator.bytecode, symbols }),
false => Err(generator.errors),
}
}
pub struct BytecodeGenerator<'a> {
- definitions: &'a HashMap<String, Tracked<Definition>>,
- labels: HashMap<String, LabelInformation>,
+ definitions: &'a IndexMap<String, Tracked<Definition>>,
+ labels: IndexMap<String, LabelInformation>,
stack: Vec<usize>,
bytecode: Vec<u8>,
errors: Vec<Tracked<BytecodeError>>,
@@ -41,8 +35,8 @@ struct LabelInformation {
}
impl<'a> BytecodeGenerator<'a> {
- pub fn new(definitions: &'a HashMap<String, Tracked<Definition>>) -> Self {
- let mut labels = HashMap::new();
+ pub fn new(definitions: &'a IndexMap<String, Tracked<Definition>>) -> Self {
+ let mut labels = IndexMap::new();
for (name, definition) in definitions {
if let DefinitionVariant::LabelDefinition = definition.variant {
// Use fake address for now.
@@ -61,9 +55,7 @@ impl<'a> BytecodeGenerator<'a> {
pub fn parse(&mut self, tokens: &[Tracked<SemanticToken>], in_macro: bool) {
macro_rules! byte {
- ($byte:expr) => {
- self.bytecode.push($byte)
- };
+ ($byte:expr) => { self.bytecode.push($byte) };
}
macro_rules! double {
($double:expr) => {{
@@ -140,7 +132,7 @@ impl<'a> BytecodeGenerator<'a> {
}
}
- if !self.stack.is_empty() {
+ if !in_macro && !self.stack.is_empty() {
unreachable!("Uncaught unterminated block");
}
}