aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler.rs15
-rw-r--r--src/typechecker.rs27
-rw-r--r--src/vm.rs52
3 files changed, 63 insertions, 31 deletions
diff --git a/src/compiler.rs b/src/compiler.rs
index d3fc1fd..f84f9f8 100644
--- a/src/compiler.rs
+++ b/src/compiler.rs
@@ -339,7 +339,11 @@ impl Compiler {
while !matches!(self.peek(), Token::RightBrace | Token::EOF) {
self.statement(block);
- expect!(self, Token::Newline, "Expect newline after expression.");
+ match self.peek() {
+ Token::Newline => { self.eat(); },
+ Token::RightBrace => { break; },
+ _ => { error!(self, "Expect newline after statement."); },
+ }
}
self.level -= 1;
@@ -374,12 +378,6 @@ impl Compiler {
} else {
block.patch(Op::JmpFalse(block.curr()), jump);
}
-
- self.expression(block);
- self.scope(block);
-
- // Loop variable
- block.add(Op::Pop, self.line());
}
fn for_loop(&mut self, block: &mut Block) {
@@ -434,6 +432,9 @@ impl Compiler {
block.add(Op::Jmp(inc), self.line());
block.patch(Op::JmpFalse(block.curr()), cond_out);
+
+ // Loop variable
+ block.add(Op::Pop, self.line());
}
fn statement(&mut self, block: &mut Block) {
diff --git a/src/typechecker.rs b/src/typechecker.rs
new file mode 100644
index 0000000..fe66200
--- /dev/null
+++ b/src/typechecker.rs
@@ -0,0 +1,27 @@
+
+#[derive(Debug)]
+pub struct TypeVM {
+ stack: Vec<Type>,
+
+ block: Block,
+ ip: usize,
+}
+
+impl TypeVM {
+ fn pop_twice(&mut self) -> (Value, Value) {
+ let (a, b) = (self.stack.pop().unwrap(), self.stack.pop().unwrap());
+ (b, a)
+ }
+
+ fn error(&self, kind: ErrorKind, message: Option<String>) -> Error {
+ Error {
+ kind,
+ file: self.block.file.clone(),
+ line: self.block.line(self.ip),
+ message,
+ }
+ }
+
+ pub fn run(&mut self) -> Result<(), Error> {
+ }
+}
diff --git a/src/vm.rs b/src/vm.rs
index bc3b1e8..4c09756 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -77,23 +77,45 @@ impl Block {
}
}
- pub fn line(&mut self, token_position: usize) {
+ pub fn add_line(&mut self, token_position: usize) {
if token_position != self.last_line_offset {
self.line_offsets.insert(self.curr(), token_position);
self.last_line_offset = token_position;
}
}
+ fn line(&self, ip: usize) -> usize {
+ for i in (0..=ip).rev() {
+ if let Some(line) = self.line_offsets.get(&i) {
+ return *line;
+ }
+ }
+ return 0;
+ }
+
+ pub fn debug_print(&self) {
+ println!(" === {} ===", self.name.blue());
+ for (i, s) in self.ops.iter().enumerate() {
+ if self.line_offsets.contains_key(&i) {
+ print!("{:5} ", self.line_offsets[&i].red());
+ } else {
+ print!(" {} ", "|".red());
+ }
+ println!("{:05} {:?}", i.blue(), s);
+ }
+ println!("");
+ }
+
pub fn add(&mut self, op: Op, token_position: usize) -> usize {
let len = self.curr();
- self.line(token_position);
+ self.add_line(token_position);
self.ops.push(op);
len
}
pub fn add_from(&mut self, ops: &[Op], token_position: usize) -> usize {
let len = self.curr();
- self.line(token_position);
+ self.add_line(token_position);
self.ops.extend_from_slice(ops);
len
}
@@ -138,20 +160,11 @@ impl VM {
self.stack.get(self.stack.len() - amount)
}
- fn line(&self) -> usize {
- for i in (0..=self.ip).rev() {
- if let Some(line) = self.block.line_offsets.get(&i) {
- return *line;
- }
- }
- return 0;
- }
-
fn error(&self, kind: ErrorKind, message: Option<String>) -> Error {
Error {
kind,
file: self.block.file.clone(),
- line: self.line(),
+ line: self.block.line(self.ip),
message,
}
}
@@ -161,16 +174,7 @@ impl VM {
const PRINT_BLOCK: bool = true;
if PRINT_BLOCK {
- println!(" === {} ===", self.block.name.blue());
- for (i, s) in self.block.ops.iter().enumerate() {
- if self.block.line_offsets.contains_key(&i) {
- print!("{:5} ", self.block.line_offsets[&i].red());
- } else {
- print!(" {} ", "|".red());
- }
- println!("{:05} {:?}", i.blue(), s);
- }
- println!("");
+ self.block.debug_print();
}
loop {
@@ -187,7 +191,7 @@ impl VM {
}
println!("]");
- println!("{:5} {:05} {:?}", self.line().red(), self.ip.blue(), self.block.ops[self.ip]);
+ println!("{:5} {:05} {:?}", self.block.line(self.ip).red(), self.ip.blue(), self.block.ops[self.ip]);
}
let op = self.block.ops[self.ip].clone();