aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/compiler.rs113
-rw-r--r--src/error.rs5
-rw-r--r--src/lib.rs388
-rw-r--r--src/main.rs8
-rw-r--r--src/vm.rs271
-rw-r--r--tihdy_derive/src/lib.rs8
6 files changed, 401 insertions, 392 deletions
diff --git a/src/compiler.rs b/src/compiler.rs
index 648989d..722b944 100644
--- a/src/compiler.rs
+++ b/src/compiler.rs
@@ -1,12 +1,12 @@
use std::{borrow::Cow, path::{Path, PathBuf}};
-use std::rc::Rc;
use std::cell::RefCell;
-use std::collections::HashMap;
use std::collections::hash_map::Entry;
+use std::collections::HashMap;
+use std::rc::Rc;
+use crate::{Blob, Block, Op, Prog, RustFunction, Type, Value};
use crate::error::{Error, ErrorKind};
use crate::tokenizer::{Token, TokenStream};
-use crate::vm::{Value, Block, Op};
macro_rules! nextable_enum {
( $name:ident { $( $thing:ident ),* $( , )? } ) => {
@@ -49,84 +49,6 @@ nextable_enum!(Prec {
Factor,
});
-
-#[derive(Clone)]
-pub struct Prog {
- pub blocks: Vec<Rc<RefCell<Block>>>,
- pub blobs: Vec<Rc<Blob>>,
- pub functions: Vec<RustFunction>,
-}
-
-#[derive(Debug, Clone)]
-pub enum Type {
- Void,
- UnknownType,
- Int,
- Float,
- Bool,
- String,
- Function(Vec<Type>, Box<Type>),
- Blob(usize),
- BlobInstance(usize),
-}
-
-impl PartialEq for Type {
- fn eq(&self, other: &Self) -> bool {
- match (self, other) {
- (Type::Void, Type::Void) => true,
- (Type::BlobInstance(a), Type::BlobInstance(b)) => a == b,
- (Type::Blob(a), Type::Blob(b)) => a == b,
- (Type::Int, Type::Int) => true,
- (Type::Float, Type::Float) => true,
- (Type::Bool, Type::Bool) => true,
- (Type::String, Type::String) => true,
- (Type::Function(a_args, a_ret), Type::Function(b_args, b_ret)) =>
- a_args == b_args && a_ret == b_ret,
- _ => false,
- }
- }
-}
-
-impl From<&Value> for Type {
- fn from(value: &Value) -> Type {
- match value {
- Value::BlobInstance(i, _) => Type::BlobInstance(*i),
- Value::Blob(i) => Type::Blob(*i),
- Value::Int(_) => Type::Int,
- Value::Float(_) => Type::Float,
- Value::Bool(_) => Type::Bool,
- Value::String(_) => Type::String,
- Value::Function(_, block) => block.borrow().ty.clone(),
- _ => Type::Void,
- }
- }
-}
-
-impl Type {
- pub fn is_unkown(&self) -> bool {
- match self {
- Type::UnknownType => true,
- _ => false,
- }
- }
-
- pub fn as_value(&self) -> Value {
- match self {
- Type::Void => Value::Nil,
- Type::Blob(i) => Value::Blob(*i),
- Type::BlobInstance(i) => Value::BlobInstance(*i, Rc::new(RefCell::new(Vec::new()))),
- Type::UnknownType => Value::Unkown,
- Type::Int => Value::Int(1),
- Type::Float => Value::Float(1.0),
- Type::Bool => Value::Bool(true),
- Type::String => Value::String(Rc::new("".to_string())),
- Type::Function(_, _) => Value::Function(
- Vec::new(),
- Rc::new(RefCell::new(Block::from_type(self)))),
- }
- }
-}
-
#[derive(Clone)]
struct Variable {
name: String,
@@ -182,35 +104,6 @@ impl Frame {
}
}
-pub type RustFunction = fn(&[Value], bool) -> Result<Value, ErrorKind>;
-
-#[derive(Debug, Clone)]
-pub struct Blob {
- pub name: String,
-
- pub name_to_field: HashMap<String, (usize, Type)>,
-}
-
-impl Blob {
- pub fn new(name: &str) -> Self {
- Self {
- name: String::from(name),
- name_to_field: HashMap::new(),
- }
- }
-
- pub fn add_field(&mut self, name: &str, ty: Type) -> Result<(), ()> {
- let size = self.name_to_field.len();
- let entry = self.name_to_field.entry(String::from(name));
- if matches!(entry, Entry::Occupied(_)) {
- Err(())
- } else {
- entry.or_insert((size, ty));
- Ok(())
- }
- }
-}
-
struct Compiler {
curr: usize,
tokens: TokenStream,
diff --git a/src/error.rs b/src/error.rs
index b489cd1..2caced9 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -2,11 +2,12 @@ use std::fmt;
use std::fs::File;
use std::io::{self, BufRead};
use std::path::PathBuf;
+
use owo_colors::OwoColorize;
-use crate::compiler::Type;
+use crate::{Op, Value};
+use crate::Type;
use crate::tokenizer::Token;
-use crate::vm::{Op, Value};
#[derive(Debug, Clone)]
pub enum ErrorKind {
diff --git a/src/lib.rs b/src/lib.rs
index 17f680c..bdd4ae4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,14 +1,22 @@
-use std::path::Path;
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::collections::hash_map::Entry;
+use std::fmt::Debug;
+use std::path::{Path, PathBuf};
+use std::rc::Rc;
+
+use owo_colors::OwoColorize;
+
+use error::Error;
+use tokenizer::TokenStream;
+
+use crate::error::ErrorKind;
pub mod compiler;
pub mod error;
pub mod tokenizer;
pub mod vm;
-use compiler::RustFunction;
-use error::Error;
-use tokenizer::TokenStream;
-
pub fn run_file(path: &Path, print: bool, functions: Vec<(String, RustFunction)>) -> Result<(), Vec<Error>> {
run(tokenizer::file_to_tokens(path), path, print, functions)
}
@@ -34,9 +42,12 @@ pub fn run(tokens: TokenStream, path: &Path, print: bool, functions: Vec<(String
#[cfg(test)]
mod tests {
- use super::{run_file, run_string};
use std::path::Path;
+ use crate::error::ErrorKind;
+
+ use super::{run_file, run_string};
+
#[macro_export]
macro_rules! assert_errs {
($result:expr, [ $( $kind:pat ),* ]) => {
@@ -81,8 +92,6 @@ mod tests {
};
}
- use crate::error::ErrorKind;
-
#[test]
fn unreachable_token() {
assert_errs!(run_string("<!>\n", true, Vec::new()), [ErrorKind::Unreachable]);
@@ -300,3 +309,366 @@ a() <=> 4
test_file!(scoping, "tests/scoping.tdy");
test_file!(for_, "tests/for.tdy");
}
+
+#[derive(Clone)]
+pub enum Value {
+ Blob(usize),
+ BlobInstance(usize, Rc<RefCell<Vec<Value>>>),
+ Float(f64),
+ Int(i64),
+ Bool(bool),
+ String(Rc<String>),
+ Function(Vec<Rc<RefCell<UpValue>>>, Rc<RefCell<Block>>),
+ ExternFunction(usize),
+ Unkown,
+ Nil,
+}
+
+#[derive(Clone, Debug)]
+pub struct UpValue {
+ slot: usize,
+ value: Value,
+}
+
+impl UpValue {
+ fn new(value: usize) -> Self {
+ Self {
+ slot: value,
+ value: Value::Nil,
+ }
+ }
+
+ fn get(&self, stack: &[Value]) -> Value {
+ if self.is_closed() {
+ self.value.clone()
+ } else {
+ stack[self.slot].clone()
+ }
+ }
+
+ fn set(&mut self, stack: &mut [Value], value: Value) {
+ if self.is_closed() {
+ self.value = value;
+ } else {
+ stack[self.slot] = value;
+ }
+ }
+
+
+ fn is_closed(&self) -> bool {
+ self.slot == 0
+ }
+
+ fn close(&mut self, value: Value) {
+ self.slot = 0;
+ self.value = value;
+ }
+}
+
+impl Debug for Value {
+ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Value::Blob(i) => write!(fmt, "(blob {})", i),
+ Value::BlobInstance(i, v) => write!(fmt, "(inst {} {:?})", i, v),
+ Value::Float(f) => write!(fmt, "(float {})", f),
+ Value::Int(i) => write!(fmt, "(int {})", i),
+ Value::Bool(b) => write!(fmt, "(bool {})", b),
+ Value::String(s) => write!(fmt, "(string \"{}\")", s),
+ Value::Function(_, block) => write!(fmt, "(fn {}: {:?})", block.borrow().name, block.borrow().ty),
+ Value::ExternFunction(slot) => write!(fmt, "(extern fn {})", slot),
+ Value::Unkown => write!(fmt, "(unkown)"),
+ Value::Nil => write!(fmt, "(nil)"),
+ }
+ }
+}
+
+impl Value {
+ fn identity(self) -> Self {
+ match self {
+ Value::Float(_) => Value::Float(1.0),
+ Value::Int(_) => Value::Int(1),
+ Value::Bool(_) => Value::Bool(true),
+ a => a,
+ }
+ }
+
+ fn as_type(&self) -> Type {
+ match self {
+ Value::BlobInstance(i, _) => Type::BlobInstance(*i),
+ Value::Blob(i) => Type::Blob(*i),
+ Value::Float(_) => Type::Float,
+ Value::Int(_) => Type::Int,
+ Value::Bool(_) => Type::Bool,
+ Value::String(_) => Type::String,
+ Value::Function(_, block) => block.borrow().ty.clone(),
+ Value::ExternFunction(_) => Type::Void, //TODO
+ Value::Unkown => Type::UnknownType,
+ Value::Nil => Type::Void,
+ }
+ }
+}
+
+#[derive(Debug, Clone)]
+pub enum Op {
+ Illegal,
+
+ Pop,
+ PopUpvalue,
+ Constant(Value),
+
+ Get(String),
+ Set(String),
+
+ Add,
+ Sub,
+ Mul,
+ Div,
+ Neg,
+
+ And,
+ Or,
+ Not,
+
+ Jmp(usize),
+ JmpFalse(usize),
+
+ Equal, // ==
+ Less, // <
+ Greater, // >
+
+ Assert,
+ Unreachable,
+
+ ReadLocal(usize),
+ AssignLocal(usize),
+
+ ReadUpvalue(usize),
+ AssignUpvalue(usize),
+
+ Define(Type),
+
+ Call(usize),
+
+ Print,
+ Return,
+}
+
+#[derive(Debug)]
+pub struct Block {
+ pub ty: Type,
+ pub ups: Vec<(usize, bool, Type)>,
+
+ pub name: String,
+ pub file: PathBuf,
+ pub ops: Vec<Op>,
+ pub last_line_offset: usize,
+ pub line_offsets: HashMap<usize, usize>,
+ pub line: usize,
+}
+
+impl Block {
+ pub fn new(name: &str, file: &Path, line: usize) -> Self {
+ Self {
+ ty: Type::Void,
+ ups: Vec::new(),
+ name: String::from(name),
+ file: file.to_owned(),
+ ops: Vec::new(),
+ last_line_offset: 0,
+ line_offsets: HashMap::new(),
+ line,
+ }
+ }
+
+ pub fn from_type(ty: &Type) -> Self {
+ let mut block = Block::new("/empty/", Path::new(""), 0);
+ block.ty = ty.clone();
+ block
+ }
+
+ pub fn args(&self) -> &Vec<Type> {
+ if let Type::Function(ref args, _) = self.ty {
+ args
+ } else {
+ unreachable!()
+ }
+ }
+
+ pub fn ret(&self) -> &Type {
+ if let Type::Function(_, ref ret) = self.ty {
+ ret
+ } else {
+ unreachable!()
+ }
+ }
+
+ pub fn id(&self) -> (PathBuf, usize) {
+ (self.file.clone(), self.line)
+ }
+
+ pub fn last_op(&self) -> Option<&Op> {
+ self.ops.last()
+ }
+
+ 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;
+ }
+ }
+
+ pub 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 last_instruction(&mut self) -> &Op {
+ self.ops.last().unwrap()
+ }
+
+ pub fn add(&mut self, op: Op, token_position: usize) -> usize {
+ let len = self.curr();
+ 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.add_line(token_position);
+ self.ops.extend_from_slice(ops);
+ len
+ }
+
+ pub fn curr(&self) -> usize {
+ self.ops.len()
+ }
+
+ pub fn patch(&mut self, op: Op, pos: usize) {
+ self.ops[pos] = op;
+ }
+}
+
+
+#[derive(Clone)]
+pub struct Prog {
+ pub blocks: Vec<Rc<RefCell<Block>>>,
+ pub blobs: Vec<Rc<Blob>>,
+ pub functions: Vec<RustFunction>,
+}
+
+#[derive(Debug, Clone)]
+pub enum Type {
+ Void,
+ UnknownType,
+ Int,
+ Float,
+ Bool,
+ String,
+ Function(Vec<Type>, Box<Type>),
+ Blob(usize),
+ BlobInstance(usize),
+}
+
+impl PartialEq for Type {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (Type::Void, Type::Void) => true,
+ (Type::BlobInstance(a), Type::BlobInstance(b)) => a == b,
+ (Type::Blob(a), Type::Blob(b)) => a == b,
+ (Type::Int, Type::Int) => true,
+ (Type::Float, Type::Float) => true,
+ (Type::Bool, Type::Bool) => true,
+ (Type::String, Type::String) => true,
+ (Type::Function(a_args, a_ret), Type::Function(b_args, b_ret)) =>
+ a_args == b_args && a_ret == b_ret,
+ _ => false,
+ }
+ }
+}
+
+impl From<&Value> for Type {
+ fn from(value: &Value) -> Type {
+ match value {
+ Value::BlobInstance(i, _) => Type::BlobInstance(*i),
+ Value::Blob(i) => Type::Blob(*i),
+ Value::Int(_) => Type::Int,
+ Value::Float(_) => Type::Float,
+ Value::Bool(_) => Type::Bool,
+ Value::String(_) => Type::String,
+ Value::Function(_, block) => block.borrow().ty.clone(),
+ _ => Type::Void,
+ }
+ }
+}
+
+impl Type {
+ pub fn is_unkown(&self) -> bool {
+ match self {
+ Type::UnknownType => true,
+ _ => false,
+ }
+ }
+
+ pub fn as_value(&self) -> Value {
+ match self {
+ Type::Void => Value::Nil,
+ Type::Blob(i) => Value::Blob(*i),
+ Type::BlobInstance(i) => Value::BlobInstance(*i, Rc::new(RefCell::new(Vec::new()))),
+ Type::UnknownType => Value::Unkown,
+ Type::Int => Value::Int(1),
+ Type::Float => Value::Float(1.0),
+ Type::Bool => Value::Bool(true),
+ Type::String => Value::String(Rc::new("".to_string())),
+ Type::Function(_, _) => Value::Function(
+ Vec::new(),
+ Rc::new(RefCell::new(Block::from_type(self)))),
+ }
+ }
+}
+
+pub type RustFunction = fn(&[Value], bool) -> Result<Value, ErrorKind>;
+
+#[derive(Debug, Clone)]
+pub struct Blob {
+ pub name: String,
+
+ pub name_to_field: HashMap<String, (usize, Type)>,
+}
+
+impl Blob {
+ pub fn new(name: &str) -> Self {
+ Self {
+ name: String::from(name),
+ name_to_field: HashMap::new(),
+ }
+ }
+
+ pub fn add_field(&mut self, name: &str, ty: Type) -> Result<(), ()> {
+ let size = self.name_to_field.len();
+ let entry = self.name_to_field.entry(String::from(name));
+ if matches!(entry, Entry::Occupied(_)) {
+ Err(())
+ } else {
+ entry.or_insert((size, ty));
+ Ok(())
+ }
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 10b88ba..c52acc8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -41,10 +41,10 @@ fn parse_args() -> Args {
tihdy_derive::extern_function!(
extern_test
- [tihdy::vm::Value::Float(x), tihdy::vm::Value::Float(y)] -> tihdy::vm::Type::Float => {
- Ok(tihdy::vm::Value::Float(x + y))
+ [tihdy::Value::Float(x), tihdy::Value::Float(y)] -> tihdy::Type::Float => {
+ Ok(tihdy::Value::Float(x + y))
},
- [tihdy::vm::Value::Float(x)] -> tihdy::vm::Type::Float => {
- Ok(tihdy::vm::Value::Float(*x))
+ [tihdy::Value::Float(x)] -> tihdy::Type::Float => {
+ Ok(tihdy::Value::Float(*x))
},
);
diff --git a/src/vm.rs b/src/vm.rs
index 6ff2cf3..849aaa1 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -1,16 +1,15 @@
-use owo_colors::OwoColorize;
-use std::collections::HashMap;
+use std::cell::RefCell;
use std::collections::hash_map::Entry;
+use std::collections::HashMap;
use std::fmt::Debug;
-use std::path::{Path, PathBuf};
use std::rc::Rc;
-use std::cell::RefCell;
-pub use crate::compiler::Type;
+use owo_colors::OwoColorize;
-use crate::compiler::RustFunction;
+use crate::{Blob, Block, Op, Prog, UpValue, Value};
use crate::error::{Error, ErrorKind};
-use crate::compiler::{Prog, Blob};
+use crate::RustFunction;
+pub use crate::Type;
macro_rules! error {
( $thing:expr, $kind:expr) => {
@@ -21,262 +20,6 @@ macro_rules! error {
};
}
-#[derive(Clone)]
-pub enum Value {
- Blob(usize),
- BlobInstance(usize, Rc<RefCell<Vec<Value>>>),
- Float(f64),
- Int(i64),
- Bool(bool),
- String(Rc<String>),
- Function(Vec<Rc<RefCell<UpValue>>>, Rc<RefCell<Block>>),
- ExternFunction(usize),
- Unkown,
- Nil,
-}
-
-#[derive(Clone, Debug)]
-pub struct UpValue {
- slot: usize,
- value: Value,
-}
-
-impl UpValue {
- fn new(value: usize) -> Self {
- Self {
- slot: value,
- value: Value::Nil,
- }
- }
-
- fn get(&self, stack: &[Value]) -> Value {
- if self.is_closed() {
- self.value.clone()
- } else {
- stack[self.slot].clone()
- }
- }
-
- fn set(&mut self, stack: &mut [Value], value: Value) {
- if self.is_closed() {
- self.value = value;
- } else {
- stack[self.slot] = value;
- }
- }
-
-
- fn is_closed(&self) -> bool {
- self.slot == 0
- }
-
- fn close(&mut self, value: Value) {
- self.slot = 0;
- self.value = value;
- }
-}
-
-impl Debug for Value {
- fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- match self {
- Value::Blob(i) => write!(fmt, "(blob {})", i),
- Value::BlobInstance(i, v) => write!(fmt, "(inst {} {:?})", i, v),
- Value::Float(f) => write!(fmt, "(float {})", f),
- Value::Int(i) => write!(fmt, "(int {})", i),
- Value::Bool(b) => write!(fmt, "(bool {})", b),
- Value::String(s) => write!(fmt, "(string \"{}\")", s),
- Value::Function(_, block) => write!(fmt, "(fn {}: {:?})", block.borrow().name, block.borrow().ty),
- Value::ExternFunction(slot) => write!(fmt, "(extern fn {})", slot),
- Value::Unkown => write!(fmt, "(unkown)"),
- Value::Nil => write!(fmt, "(nil)"),
- }
- }
-}
-
-impl Value {
- fn identity(self) -> Self {
- match self {
- Value::Float(_) => Value::Float(1.0),
- Value::Int(_) => Value::Int(1),
- Value::Bool(_) => Value::Bool(true),
- a => a,
- }
- }
-
- fn as_type(&self) -> Type {
- match self {
- Value::BlobInstance(i, _) => Type::BlobInstance(*i),
- Value::Blob(i) => Type::Blob(*i),
- Value::Float(_) => Type::Float,
- Value::Int(_) => Type::Int,
- Value::Bool(_) => Type::Bool,
- Value::String(_) => Type::String,
- Value::Function(_, block) => block.borrow().ty.clone(),
- Value::ExternFunction(_) => Type::Void, //TODO
- Value::Unkown => Type::UnknownType,
- Value::Nil => Type::Void,
- }
- }
-}
-
-#[derive(Debug, Clone)]
-pub enum Op {
- Illegal,
-
- Pop,
- PopUpvalue,
- Constant(Value),
-
- Get(String),
- Set(String),
-
- Add,
- Sub,
- Mul,
- Div,
- Neg,
-
- And,
- Or,
- Not,
-
- Jmp(usize),
- JmpFalse(usize),
-
- Equal, // ==
- Less, // <
- Greater, // >
-
- Assert,
- Unreachable,
-
- ReadLocal(usize),
- AssignLocal(usize),
-
- ReadUpvalue(usize),
- AssignUpvalue(usize),
-
- Define(Type),
-
- Call(usize),
-
- Print,
- Return,
-}
-
-#[derive(Debug)]
-pub struct Block {
- pub ty: Type,
- pub ups: Vec<(usize, bool, Type)>,
-
- pub name: String,
- pub file: PathBuf,
- pub ops: Vec<Op>,
- pub last_line_offset: usize,
- pub line_offsets: HashMap<usize, usize>,
- pub line: usize,
-}
-
-impl Block {
- pub fn new(name: &str, file: &Path, line: usize) -> Self {
- Self {
- ty: Type::Void,
- ups: Vec::new(),
- name: String::from(name),
- file: file.to_owned(),
- ops: Vec::new(),
- last_line_offset: 0,
- line_offsets: HashMap::new(),
- line,
- }
- }
-
- pub fn from_type(ty: &Type) -> Self {
- let mut block = Block::new("/empty/", Path::new(""), 0);
- block.ty = ty.clone();
- block
- }
-
- pub fn args(&self) -> &Vec<Type> {
- if let Type::Function(ref args, _) = self.ty {
- args
- } else {
- unreachable!()
- }
- }
-
- pub fn ret(&self) -> &Type {
- if let Type::Function(_, ref ret) = self.ty {
- ret
- } else {
- unreachable!()
- }
- }
-
- pub fn id(&self) -> (PathBuf, usize) {
- (self.file.clone(), self.line)
- }
-
- pub fn last_op(&self) -> Option<&Op> {
- self.ops.last()
- }
-
- 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;
- }
- }
-
- pub 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 last_instruction(&mut self) -> &Op {
- self.ops.last().unwrap()
- }
-
- pub fn add(&mut self, op: Op, token_position: usize) -> usize {
- let len = self.curr();
- 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.add_line(token_position);
- self.ops.extend_from_slice(ops);
- len
- }
-
- pub fn curr(&self) -> usize {
- self.ops.len()
- }
-
- pub fn patch(&mut self, op: Op, pos: usize) {
- self.ops[pos] = op;
- }
-}
-
#[derive(Debug)]
struct Frame {
stack_offset: usize,
@@ -973,8 +716,8 @@ impl VM {
#[cfg(test)]
mod tests {
mod typing {
- use crate::test_string;
use crate::error::ErrorKind;
+ use crate::test_string;
test_string!(uncallable_type, "
f := fn i: int {
diff --git a/tihdy_derive/src/lib.rs b/tihdy_derive/src/lib.rs
index 7950d20..c0806ab 100644
--- a/tihdy_derive/src/lib.rs
+++ b/tihdy_derive/src/lib.rs
@@ -65,20 +65,20 @@ pub fn extern_function(tokens: TokenStream) -> TokenStream {
let tokens = quote! {
pub fn #function (
- __values: &[tihdy::vm::Value],
+ __values: &[tihdy::Value],
__typecheck: bool
- ) -> ::std::result::Result<tihdy::vm::Value, tihdy::error::ErrorKind>
+ ) -> ::std::result::Result<tihdy::Value, tihdy::error::ErrorKind>
{
if __typecheck {
#[allow(unused_variables)]
match __values {
#(#typecheck_blocks),*
- _ => Err(tihdy::error::ErrorKind::ExternTypeMismatch(stringify!(#function).to_string(), __values.iter().map(|v| tihdy::vm::Type::from(v)).collect()))
+ _ => Err(tihdy::error::ErrorKind::ExternTypeMismatch(stringify!(#function).to_string(), __values.iter().map(|v| tihdy::Type::from(v)).collect()))
}
} else {
match __values {
#(#eval_blocks),*
- _ => Err(tihdy::error::ErrorKind::ExternTypeMismatch(stringify!(#function).to_string(), __values.iter().map(|v| tihdy::vm::Type::from(v)).collect()))
+ _ => Err(tihdy::error::ErrorKind::ExternTypeMismatch(stringify!(#function).to_string(), __values.iter().map(|v| tihdy::Type::from(v)).collect()))
}
}
}