Globals work, sizes are no longer part of the grammar
This commit is contained in:
@@ -18,7 +18,6 @@ impl Compilable for Assignment {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::compiler::test_utils::*;
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -7,8 +7,8 @@ use crate::compiler::utils::Variable;
|
||||
|
||||
impl Compilable for Global {
|
||||
fn process(self, state: &mut State, _: Option<&mut CompiledFn>, _loc: Location) -> Result<(), CompileError> {
|
||||
if self.size.is_some() {
|
||||
todo!("Global arrays are not yet supported")
|
||||
if self.initial.is_some() {
|
||||
todo!("Globals with initials are not yet supported")
|
||||
}
|
||||
state.add_global(&self.name, |s| Variable::IndirectLabel(s.gensym()))
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ impl Compilable for RepeatLoop {
|
||||
if named_counter {
|
||||
let decl = VarDecl {
|
||||
name: counter_name.clone(),
|
||||
size: None,
|
||||
initial: Some(Expr::Number(0)),
|
||||
};
|
||||
decl.process(state, Some(sig), loc)?;
|
||||
|
||||
@@ -7,9 +7,6 @@ use crate::compiler::state::State;
|
||||
impl Compilable for VarDecl {
|
||||
fn process(self, state: &mut State, sig: Option<&mut CompiledFn>, loc: Location) -> Result<(), CompileError> {
|
||||
let sig = sig.expect("Var declaration outside function");
|
||||
if self.size.is_some() {
|
||||
todo!("Arrays are not yet supported")
|
||||
}
|
||||
if let Some(initial) = self.initial {
|
||||
// If it's got an initial value, we have to compile that before we add
|
||||
// the name to scope, or else UB will ensue if it refers to itself:
|
||||
|
||||
@@ -211,7 +211,6 @@ impl CompiledFn {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::compiler::test_utils::*;
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -44,6 +44,13 @@ pub fn build_boot(src: &str) -> Result<Vec<String>, CompileError> {
|
||||
for (label, val) in state.strings.iter() {
|
||||
asm.push(format!("{}: .db \"{}\\0\"", label, val))
|
||||
}
|
||||
for (label, val) in state.global_scope.iter() {
|
||||
// All global variables are indirect labels; anything in scope that's not that is a const,
|
||||
// fn, or string, which we'll emit elsewhere.
|
||||
if let Variable::IndirectLabel(label) = val {
|
||||
asm.push(format!("{}: .db 0", label))
|
||||
}
|
||||
}
|
||||
for (_, val) in state.functions.iter_mut() {
|
||||
asm.push(format!("{}:", val.label));
|
||||
asm.append(val.preamble.as_mut());
|
||||
@@ -118,7 +125,24 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_global_vars() {
|
||||
|
||||
// Trying a non-str global var
|
||||
let asm = build_boot("global foo; fn main() { foo = 3; }".into()).unwrap();
|
||||
assert_eq!(asm.join("\n"), vec![
|
||||
".org 0x400",
|
||||
"push stack",
|
||||
"call _forge_gensym_2",
|
||||
"hlt",
|
||||
"_forge_gensym_1: .db 0", // The global var
|
||||
"_forge_gensym_2:", // main()
|
||||
"dup", "pushr", "pushr", // The frame is zero length; that's a global we're assigning to
|
||||
"push 3", // rvalue
|
||||
"push _forge_gensym_1", // lvalue
|
||||
"storew",
|
||||
"push 0",
|
||||
"_forge_gensym_3:",
|
||||
"popr", "pop", "popr", "pop", "ret",
|
||||
"stack: .db 0",
|
||||
].join("\n"))
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user