Lint
This commit is contained in:
+75
-76
@@ -260,7 +260,7 @@ trait Compilable {
|
|||||||
self,
|
self,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
function: Option<&mut CompiledFn>,
|
function: Option<&mut CompiledFn>,
|
||||||
location: Location
|
location: Location,
|
||||||
) -> Result<(), CompileError>;
|
) -> Result<(), CompileError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +318,7 @@ impl Compilable for Block {
|
|||||||
sig.emit("pop")
|
sig.emit("pop")
|
||||||
}
|
}
|
||||||
Statement::VarDecl(vardecl) => vardecl.process(state, Some(sig), loc)?,
|
Statement::VarDecl(vardecl) => vardecl.process(state, Some(sig), loc)?,
|
||||||
Statement::Asm(Asm { args, body}) => {
|
Statement::Asm(Asm { args, body }) => {
|
||||||
// Process all the args, if any
|
// Process all the args, if any
|
||||||
for a in args {
|
for a in args {
|
||||||
(*a.0).process(state, Some(sig), loc)?
|
(*a.0).process(state, Some(sig), loc)?
|
||||||
@@ -365,72 +365,71 @@ impl Compilable for RepeatLoop {
|
|||||||
fn process(self, state: &mut State, sig: Option<&mut CompiledFn>, loc: Location) -> Result<(), CompileError> {
|
fn process(self, state: &mut State, sig: Option<&mut CompiledFn>, loc: Location) -> Result<(), CompileError> {
|
||||||
let sig = sig.expect("Repeat loop outside function");
|
let sig = sig.expect("Repeat loop outside function");
|
||||||
|
|
||||||
if let RepeatLoop{ count, name, body } = self {
|
let RepeatLoop { count, name, body } = self;
|
||||||
let named_counter = name.is_some();
|
let named_counter = name.is_some();
|
||||||
let mut counter_name = String::new();
|
let mut counter_name = String::new();
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
counter_name = name;
|
counter_name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if named_counter {
|
if named_counter {
|
||||||
let decl = VarDecl{
|
let decl = VarDecl {
|
||||||
name: counter_name.clone(),
|
name: counter_name.clone(),
|
||||||
size: None,
|
size: None,
|
||||||
initial: Some(Expr::Number(0)),
|
initial: Some(Expr::Number(0)),
|
||||||
};
|
};
|
||||||
decl.process(state, Some(sig), loc)?;
|
decl.process(state, Some(sig), loc)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Okay, the counter (if present) is now declared and in scope; we'll eval the limit once
|
// Okay, the counter (if present) is now declared and in scope; we'll eval the limit once
|
||||||
count.process(state, Some(sig), loc)?;
|
count.process(state, Some(sig), loc)?;
|
||||||
|
|
||||||
// Now we have a fairly normal while loop:
|
// Now we have a fairly normal while loop:
|
||||||
sig.emit("#while");
|
sig.emit("#while");
|
||||||
// Stack currently has the limit on top. We need to cmp the counter to that.
|
// Stack currently has the limit on top. We need to cmp the counter to that.
|
||||||
|
sig.emit("dup");
|
||||||
|
|
||||||
|
// Load the counter, if present:
|
||||||
|
if named_counter {
|
||||||
|
Expr::Name(counter_name.clone()).process(state, Some(sig), loc)?;
|
||||||
|
// Subtract the counter from (the copy of) the limit.
|
||||||
|
sig.emit("sub");
|
||||||
|
}
|
||||||
|
|
||||||
|
// cmp that to zero, for our flag: this is either limit - ctr or limit, depending if
|
||||||
|
// there's a counter
|
||||||
|
sig.emit_arg("agt", 0);
|
||||||
|
|
||||||
|
// Loop body:
|
||||||
|
sig.emit("#do");
|
||||||
|
body.process(state, Some(sig), loc)?;
|
||||||
|
|
||||||
|
// After the body we need to increment the counter if there is one
|
||||||
|
if named_counter {
|
||||||
|
// Put its address on top:
|
||||||
|
Expr::Address(Expr::Name(counter_name.clone()).into()).process(state, Some(sig), loc)?;
|
||||||
|
// Dup and load it:
|
||||||
sig.emit("dup");
|
sig.emit("dup");
|
||||||
|
sig.emit("loadw");
|
||||||
|
// Increment it:
|
||||||
|
sig.emit_arg("add", 1);
|
||||||
|
// Now we have ( counted-addr new-ctr-val ) so swap and store
|
||||||
|
sig.emit("swap");
|
||||||
|
sig.emit("storew");
|
||||||
|
} else {
|
||||||
|
// No counter, so just decrement the limit, which is already on top:
|
||||||
|
sig.emit_arg("sub", 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Load the counter, if present:
|
// Back to the check!
|
||||||
if named_counter {
|
sig.emit("#end");
|
||||||
Expr::Name(counter_name.clone()).process(state, Some(sig), loc)?;
|
// Done with the loop, but the limit is still on the stack, pop it:
|
||||||
// Subtract the counter from (the copy of) the limit.
|
sig.emit("pop");
|
||||||
sig.emit("sub");
|
|
||||||
}
|
|
||||||
|
|
||||||
// cmp that to zero, for our flag: this is either limit - ctr or limit, depending if
|
// If we have added a counter variable, we need to forget that because (even
|
||||||
// there's a counter
|
// though declared outside the block) it should be scoped to the block:
|
||||||
sig.emit_arg("agt", 0);
|
if named_counter {
|
||||||
|
sig.forget_last_local();
|
||||||
// Loop body:
|
|
||||||
sig.emit("#do");
|
|
||||||
body.process(state, Some(sig), loc)?;
|
|
||||||
|
|
||||||
// After the body we need to increment the counter if there is one
|
|
||||||
if named_counter {
|
|
||||||
// Put its address on top:
|
|
||||||
Expr::Address(Expr::Name(counter_name.clone()).into()).process(state, Some(sig), loc)?;
|
|
||||||
// Dup and load it:
|
|
||||||
sig.emit("dup");
|
|
||||||
sig.emit("loadw");
|
|
||||||
// Increment it:
|
|
||||||
sig.emit_arg("add", 1);
|
|
||||||
// Now we have ( counted-addr new-ctr-val ) so swap and store
|
|
||||||
sig.emit("swap");
|
|
||||||
sig.emit("storew");
|
|
||||||
} else {
|
|
||||||
// No counter, so just decrement the limit, which is already on top:
|
|
||||||
sig.emit_arg("sub", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Back to the check!
|
|
||||||
sig.emit("#end");
|
|
||||||
// Done with the loop, but the limit is still on the stack, pop it:
|
|
||||||
sig.emit("pop");
|
|
||||||
|
|
||||||
// If we have added a counter variable, we need to forget that because (even
|
|
||||||
// though declared outside the block) it should be scoped to the block:
|
|
||||||
if named_counter {
|
|
||||||
sig.forget_last_local();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -609,7 +608,7 @@ impl Compilable for Call {
|
|||||||
sig.emit("pushr");
|
sig.emit("pushr");
|
||||||
|
|
||||||
// Now we increment the frame ptr to right after the current frame:
|
// Now we increment the frame ptr to right after the current frame:
|
||||||
let frame_size = sig.frame_size();
|
let frame_size = sig.frame_size();
|
||||||
if frame_size > 0 {
|
if frame_size > 0 {
|
||||||
sig.emit("loadw frame");
|
sig.emit("loadw frame");
|
||||||
sig.emit_arg("add", frame_size);
|
sig.emit_arg("add", frame_size);
|
||||||
@@ -1052,7 +1051,7 @@ mod test {
|
|||||||
vec![
|
vec![
|
||||||
("_forge_gensym_1".into(), "foo".into()),
|
("_forge_gensym_1".into(), "foo".into()),
|
||||||
("_forge_gensym_3".into(), "bar".into()), // gensym 2 is the entrypoint of blah()
|
("_forge_gensym_3".into(), "bar".into()), // gensym 2 is the entrypoint of blah()
|
||||||
("_forge_gensym_4".into(), "norp".into())
|
("_forge_gensym_4".into(), "norp".into()),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -1064,7 +1063,7 @@ mod test {
|
|||||||
"push _forge_gensym_4",
|
"push _forge_gensym_4",
|
||||||
"loadw frame",
|
"loadw frame",
|
||||||
"add 3", // the address of y (frame + 3) and put gensym_4 in it
|
"add 3", // the address of y (frame + 3) and put gensym_4 in it
|
||||||
"storew"
|
"storew",
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
)
|
)
|
||||||
@@ -1081,7 +1080,7 @@ mod test {
|
|||||||
"loadw frame", // The addr of x
|
"loadw frame", // The addr of x
|
||||||
"loadw frame",
|
"loadw frame",
|
||||||
"add 3", // the address of y (frame + 3) and put the addr of x (frame) in it
|
"add 3", // the address of y (frame + 3) and put the addr of x (frame) in it
|
||||||
"storew"
|
"storew",
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
)
|
)
|
||||||
@@ -1099,7 +1098,7 @@ mod test {
|
|||||||
"loadw",
|
"loadw",
|
||||||
"loadw", // Then load the value at 3
|
"loadw", // Then load the value at 3
|
||||||
"push 1000", // Push the addr 1000, for the lvalue
|
"push 1000", // Push the addr 1000, for the lvalue
|
||||||
"storew" // Store whatever's at 3 to 1000
|
"storew", // Store whatever's at 3 to 1000
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
)
|
)
|
||||||
@@ -1114,7 +1113,7 @@ mod test {
|
|||||||
"push 3", // so 3 is the string "bar"
|
"push 3", // so 3 is the string "bar"
|
||||||
"add", // Add 3 to that address
|
"add", // Add 3 to that address
|
||||||
"loadw frame", // Store it in the first var
|
"loadw frame", // Store it in the first var
|
||||||
"storew"
|
"storew",
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
)
|
)
|
||||||
@@ -1127,7 +1126,7 @@ mod test {
|
|||||||
vec![
|
vec![
|
||||||
"loadw frame", // Push the addr of x
|
"loadw frame", // Push the addr of x
|
||||||
"swap 12", // The asm body, which swaps 12 behind it and stores it there
|
"swap 12", // The asm body, which swaps 12 behind it and stores it there
|
||||||
"storew"
|
"storew",
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
)
|
)
|
||||||
@@ -1211,7 +1210,7 @@ mod test {
|
|||||||
"loadw frame",
|
"loadw frame",
|
||||||
"add 3",
|
"add 3",
|
||||||
"storew", // c = c + 1
|
"storew", // c = c + 1
|
||||||
"#end" // End the loop body
|
"#end", // End the loop body
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
);
|
);
|
||||||
@@ -1252,7 +1251,7 @@ mod test {
|
|||||||
"call", // Actually make the call
|
"call", // Actually make the call
|
||||||
"popr", // Restore the frame ptr
|
"popr", // Restore the frame ptr
|
||||||
"storew frame",
|
"storew frame",
|
||||||
"pop" // expr-as-statement drops the evaluated value
|
"pop", // expr-as-statement drops the evaluated value
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
);
|
);
|
||||||
@@ -1339,7 +1338,7 @@ mod test {
|
|||||||
"loadw frame", // Load x so we can return it
|
"loadw frame", // Load x so we can return it
|
||||||
"add 3",
|
"add 3",
|
||||||
"loadw",
|
"loadw",
|
||||||
"ret"
|
"ret",
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
);
|
);
|
||||||
@@ -1374,7 +1373,7 @@ mod test {
|
|||||||
"loadw frame", // Load x so we can return it
|
"loadw frame", // Load x so we can return it
|
||||||
"add 3",
|
"add 3",
|
||||||
"loadw",
|
"loadw",
|
||||||
"ret"
|
"ret",
|
||||||
].join("\n")
|
].join("\n")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1391,7 +1390,7 @@ mod test {
|
|||||||
"push 5",
|
"push 5",
|
||||||
"ret",
|
"ret",
|
||||||
"frame: .db $+1",
|
"frame: .db $+1",
|
||||||
".db 0"
|
".db 0",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
|
|
||||||
// Slightly more complicated, with a global str
|
// Slightly more complicated, with a global str
|
||||||
@@ -1405,7 +1404,7 @@ mod test {
|
|||||||
"push _forge_gensym_1",
|
"push _forge_gensym_1",
|
||||||
"ret",
|
"ret",
|
||||||
"frame: .db $+1",
|
"frame: .db $+1",
|
||||||
".db 0"
|
".db 0",
|
||||||
].join("\n"))
|
].join("\n"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1440,7 +1439,7 @@ mod test {
|
|||||||
"storew", // taking the same (now freed) frame slot that c took, because c is
|
"storew", // taking the same (now freed) frame slot that c took, because c is
|
||||||
"loadw frame", // now out of scope
|
"loadw frame", // now out of scope
|
||||||
"loadw",
|
"loadw",
|
||||||
"ret"
|
"ret",
|
||||||
]
|
]
|
||||||
.join("\n")
|
.join("\n")
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user