Fixing bug with if statement 'end'.
This commit is contained in:
parent
84c6e71646
commit
d2f47604bf
2 changed files with 60 additions and 34 deletions
78
src/lib.rs
78
src/lib.rs
|
|
@ -16,6 +16,8 @@ struct Reader<'a> { // 'cursor' states that follow through parsed source
|
|||
white: bool, // Is the previous 'thing' whitespace?
|
||||
}
|
||||
|
||||
type Error = String;
|
||||
|
||||
pub struct LoadError(String, Piece<()>); // Any error returned by a machine loading code
|
||||
|
||||
impl LoadError {
|
||||
|
|
@ -25,8 +27,27 @@ impl LoadError {
|
|||
fn from<T>(message: &str, piece: &Piece<T>) -> LoadError {
|
||||
LoadError(message.to_string(), piece.unit())
|
||||
}
|
||||
fn msg(&self, reader: &Reader) -> String {
|
||||
self.0.clone().add(reader.slice)
|
||||
fn msg(&self, reader: &str) -> String {
|
||||
let mut roll = format!("Error: {} {}",self.1.index,self.0);
|
||||
let mut begin = self.1.index;
|
||||
let mut end = self.1.index + self.1.width;
|
||||
let mut count = 0;
|
||||
for line in reader.lines() { // todo: improve this
|
||||
count += 1;
|
||||
if line.len() >= begin {
|
||||
begin = 0;
|
||||
roll = roll.add(format!("\n{}\t",count).as_str());
|
||||
roll = roll.add(line);
|
||||
} else {
|
||||
begin -= line.len();
|
||||
}
|
||||
if line.len() > end {
|
||||
break;
|
||||
} else {
|
||||
end -= line.len()
|
||||
}
|
||||
}
|
||||
roll
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -928,9 +949,12 @@ impl Parse for Statement {
|
|||
))
|
||||
} else {
|
||||
let names = reader.take::<Vec<Piece<Name>>>()?.it;
|
||||
reader.consume_white("=")?;
|
||||
let expressions = reader.take::<Vec<Piece<Expression>>>()?.it;
|
||||
*reader = *reader;
|
||||
let expressions = if reader.consume_white("=").is_ok() {
|
||||
reader.take::<Vec<Piece<Expression>>>()?.it
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
*reader = *reader; // todo: what are these
|
||||
Ok(Piece::from(
|
||||
Statement::Declaration(names, expressions),
|
||||
&start,
|
||||
|
|
@ -2354,7 +2378,12 @@ impl Code {
|
|||
}
|
||||
|
||||
impl Machine {
|
||||
fn load(&mut self, source: &str) -> Result<Callable, LoadError> {
|
||||
fn load(&mut self, source: &str) -> Result<Callable, Error> {
|
||||
let parsed = match parse(source) {
|
||||
Ok(parsed) => parsed,
|
||||
Err(error) => return Err(error.msg(source))
|
||||
};
|
||||
|
||||
let mut traversal = Traversal{contexts: vec![Context {
|
||||
scopes: vec![Scope { // Dummy initial scope so the rest can start from index = 0
|
||||
index: 0,
|
||||
|
|
@ -2376,12 +2405,21 @@ impl Machine {
|
|||
code: vec![],
|
||||
},
|
||||
}]};
|
||||
parse(source)?.compile(&mut traversal)?;
|
||||
|
||||
match parsed.compile(&mut traversal) {
|
||||
Ok(compiled) => compiled,
|
||||
Err(error) => return Err(error.msg(source))
|
||||
};
|
||||
|
||||
let prototype = match traversal.close_context() {
|
||||
Ok(compiled) => compiled,
|
||||
Err(error) => return Err(error.msg(source))
|
||||
};
|
||||
|
||||
let global = self.global.clone();
|
||||
let upvalues = vec![self.allocator.alloc(Upvalue::Heap(Value::Table(global)))];
|
||||
Ok(Callable::Mars(self.allocator.alloc(Closure {
|
||||
prototype: Rc::new(traversal.close_context()?),
|
||||
prototype: Rc::new(prototype),
|
||||
upvalues,
|
||||
})))
|
||||
}
|
||||
|
|
@ -2624,18 +2662,17 @@ impl Machine {
|
|||
}
|
||||
Code::IteratorLoop(offset) => {
|
||||
let len = needle.stack.len();
|
||||
let function_index = len - 2;
|
||||
let state_index = len - 1;
|
||||
let var_index = len;
|
||||
let function = needle.stack[function_index].value.clone();
|
||||
let state = needle.stack[state_index].value.clone();
|
||||
let var = needle.stack[var_index].value.clone();
|
||||
let function = needle.stack[len - 2].value.clone();
|
||||
let state = needle.stack[len - 1].value.clone();
|
||||
let var = needle.stack[len].value.clone();
|
||||
needle.push(function);
|
||||
needle.push(var);
|
||||
needle.push(state);
|
||||
let offset = frame.offset;
|
||||
frame = call(self, needle,frame,Index::try_from(needle.stack.len() - offset - 2).unwrap())?;
|
||||
needle.stack.get(len + 2).unwrap_or(&Register::NIL);
|
||||
needle.push(var);
|
||||
let frame_offset = frame.offset;
|
||||
frame = call(self, needle,frame,Index::try_from(needle.stack.len() - frame_offset - 2).unwrap())?;
|
||||
if needle.stack.get(len + 1).unwrap_or(&Register::NIL).value == Value::Nil {
|
||||
jump(&mut frame, offset);
|
||||
};
|
||||
}
|
||||
}
|
||||
frame.counter += 1;
|
||||
|
|
@ -2670,6 +2707,9 @@ mod tests {
|
|||
fn simple() {
|
||||
let mut machine = Machine::new();
|
||||
let result = machine.load(include_str!("tests/script.lua"));
|
||||
println!("{:#?}", result);
|
||||
match result {
|
||||
Err(error) => println!("{}",error),
|
||||
Ok(result) => println!("{:?}",result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +1 @@
|
|||
local two
|
||||
do
|
||||
local one
|
||||
if something then
|
||||
local three
|
||||
print(something)
|
||||
end
|
||||
local four
|
||||
if something2 then
|
||||
|
||||
end
|
||||
end
|
||||
local function bricked(hello, there)
|
||||
|
||||
end
|
||||
do end
|
||||
Loading…
Add table
Add a link
Reference in a new issue