Run rustfmt

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-10-20 16:21:50 -07:00
parent ceda48988d
commit 692bb521ec
27 changed files with 402 additions and 251 deletions

View File

@@ -11,8 +11,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut parser_builder = CTParserBuilder::new() let mut parser_builder = CTParserBuilder::new()
.yacckind(YaccKind::Grmtools) .yacckind(YaccKind::Grmtools)
.error_on_conflicts(false); .error_on_conflicts(false);
let lex_rule_ids_map = parser_builder let lex_rule_ids_map = parser_builder.process_file_in_src("syn/parser.y")?;
.process_file_in_src("syn/parser.y")?;
if let Some((grm, _, _, conflicts)) = parser_builder.conflicts() { if let Some((grm, _, _, conflicts)) = parser_builder.conflicts() {
eprintln!("{}", conflicts.pp(grm)); eprintln!("{}", conflicts.pp(grm));
return Err("conflicts in parser".into()); return Err("conflicts in parser".into());

View File

@@ -1,4 +1,4 @@
use not_python::{syn::ast, compile::Compile, vm::Vm}; use not_python::{compile::Compile, syn::ast, vm::Vm};
use std::{fs, path::PathBuf}; use std::{fs, path::PathBuf};
use structopt::StructOpt; use structopt::StructOpt;
@@ -18,7 +18,6 @@ struct Options {
#[structopt(short = "d", long)] #[structopt(short = "d", long)]
disassemble: bool, disassemble: bool,
*/ */
#[structopt(long, default_value = "run")] #[structopt(long, default_value = "run")]
action: String, action: String,
} }
@@ -28,8 +27,8 @@ fn main() -> Result<()> {
let text = fs::read_to_string(&opt.input)?; let text = fs::read_to_string(&opt.input)?;
let action = &opt.action.to_lowercase(); let action = &opt.action.to_lowercase();
match action.as_str() { match action.as_str() {
"run" | "parse" | "dump" => {}, "run" | "parse" | "dump" => {}
_ => eprintln!("WARNING: unknown action {}", action) _ => eprintln!("WARNING: unknown action {}", action),
} }
let ast = match ast::parse(text.as_str()) { let ast = match ast::parse(text.as_str()) {
@@ -40,7 +39,8 @@ fn main() -> Result<()> {
} }
return Err("errors reported, exiting".into()); return Err("errors reported, exiting".into());
} }
}.unwrap(); }
.unwrap();
if action == "parse" { if action == "parse" {
println!("{:#?}", ast); println!("{:#?}", ast);
return Ok(()); return Ok(());

View File

@@ -10,4 +10,3 @@ pub enum Error {
} }
pub type Result<T, E = Error> = std::result::Result<T, E>; pub type Result<T, E = Error> = std::result::Result<T, E>;

View File

@@ -1,4 +1,8 @@
use crate::{compile::Compile, obj::prelude::*, syn::{ast::*, visit::*}}; use crate::{
compile::Compile,
obj::prelude::*,
syn::{ast::*, visit::*},
};
/// Collects local names from the given tree. /// Collects local names from the given tree.
/// ///
@@ -30,10 +34,18 @@ impl<'c> CollectLocals<'c> {
impl Visit for CollectLocals<'_> { impl Visit for CollectLocals<'_> {
type Out = (); type Out = ();
fn visit_body(&mut self, body: &Body) -> Self::Out { DefaultAccept::default_accept(body, self); } fn visit_body(&mut self, body: &Body) -> Self::Out {
fn visit_stmt(&mut self, stmt: &Stmt) -> Self::Out { DefaultAccept::default_accept(stmt, self); } DefaultAccept::default_accept(body, self);
fn visit_assign_stmt(&mut self, assign: &AssignStmt) -> Self::Out { DefaultAccept::default_accept(assign, self); } }
fn visit_return_stmt(&mut self, ret: &ReturnStmt) -> Self::Out { DefaultAccept::default_accept(ret, self); } fn visit_stmt(&mut self, stmt: &Stmt) -> Self::Out {
DefaultAccept::default_accept(stmt, self);
}
fn visit_assign_stmt(&mut self, assign: &AssignStmt) -> Self::Out {
DefaultAccept::default_accept(assign, self);
}
fn visit_return_stmt(&mut self, ret: &ReturnStmt) -> Self::Out {
DefaultAccept::default_accept(ret, self);
}
fn visit_lhs_expr(&mut self, lhs_expr: &LhsExpr) -> Self::Out { fn visit_lhs_expr(&mut self, lhs_expr: &LhsExpr) -> Self::Out {
match lhs_expr { match lhs_expr {
LhsExpr::Name(name) => { LhsExpr::Name(name) => {
@@ -43,14 +55,28 @@ impl Visit for CollectLocals<'_> {
_ => { /* no op */ } _ => { /* no op */ }
} }
} }
fn visit_expr(&mut self, expr: &Expr) -> Self::Out { DefaultAccept::default_accept(expr, self); } fn visit_expr(&mut self, expr: &Expr) -> Self::Out {
fn visit_bin_expr(&mut self, expr: &BinExpr) -> Self::Out { DefaultAccept::default_accept(expr, self); } DefaultAccept::default_accept(expr, self);
fn visit_un_expr(&mut self, expr: &UnExpr) -> Self::Out { DefaultAccept::default_accept(expr, self); } }
fn visit_call_expr(&mut self, expr: &CallExpr) -> Self::Out { DefaultAccept::default_accept(expr, self); } fn visit_bin_expr(&mut self, expr: &BinExpr) -> Self::Out {
fn visit_index_expr(&mut self, expr: &IndexExpr) -> Self::Out { DefaultAccept::default_accept(expr, self); } DefaultAccept::default_accept(expr, self);
fn visit_access_expr(&mut self, expr: &AccessExpr) -> Self::Out { DefaultAccept::default_accept(expr, self); } }
fn visit_un_expr(&mut self, expr: &UnExpr) -> Self::Out {
DefaultAccept::default_accept(expr, self);
}
fn visit_call_expr(&mut self, expr: &CallExpr) -> Self::Out {
DefaultAccept::default_accept(expr, self);
}
fn visit_index_expr(&mut self, expr: &IndexExpr) -> Self::Out {
DefaultAccept::default_accept(expr, self);
}
fn visit_access_expr(&mut self, expr: &AccessExpr) -> Self::Out {
DefaultAccept::default_accept(expr, self);
}
fn visit_fun_expr(&mut self, _expr: &FunExpr) -> Self::Out { fn visit_fun_expr(&mut self, _expr: &FunExpr) -> Self::Out {
// Do not collect names for function expressions, since they have their own scope. // Do not collect names for function expressions, since they have their own scope.
} }
fn visit_atom(&mut self, atom: &Atom) -> Self::Out { DefaultAccept::default_accept(atom, self); } fn visit_atom(&mut self, atom: &Atom) -> Self::Out {
DefaultAccept::default_accept(atom, self);
}
} }

View File

@@ -4,7 +4,7 @@ mod locals;
mod scope; mod scope;
pub mod thunk; pub mod thunk;
use crate::{syn::ast::Body, obj::prelude::*, vm::consts::*}; use crate::{obj::prelude::*, syn::ast::Body, vm::consts::*};
use scope::*; use scope::*;
use std::collections::HashMap; use std::collections::HashMap;
@@ -29,20 +29,28 @@ impl Compile {
.to_vec(); .to_vec();
// XXX TODO(compile) // XXX TODO(compile)
// remove this when we get returns implemented // remove this when we get returns implemented
main.push(crate::vm::inst::Inst::PushSym(crate::obj::reserved::NIL_NAME.sym)); main.push(crate::vm::inst::Inst::PushSym(
crate::obj::reserved::NIL_NAME.sym,
));
main.push(crate::vm::inst::Inst::Return); main.push(crate::vm::inst::Inst::Return);
let globals_syms: std::collections::BTreeMap<_, _> = self.pop_scope_layer().unwrap() let globals_syms: std::collections::BTreeMap<_, _> = self
.pop_scope_layer()
.unwrap()
.into_iter() .into_iter()
.map(|(sym, name)| (name, sym)) .map(|(sym, name)| (name, sym))
.collect(); .collect();
let globals = globals_syms.into_iter() let globals = globals_syms
.into_iter()
.enumerate() .enumerate()
.map(|(index, (name, sym))| { .map(|(index, (name, sym))| {
assert_eq!(index, name.index()); assert_eq!(index, name.index());
sym sym
}) })
.collect(); .collect();
Ok((self.const_data.const_pool, UserFun::new_obj(main, globals, 0))) Ok((
self.const_data.const_pool,
UserFun::new_obj(main, globals, 0),
))
} }
/// Gets the constant data that is interned in this compile session. /// Gets the constant data that is interned in this compile session.

View File

@@ -11,9 +11,7 @@ pub struct Scope {
impl Scope { impl Scope {
pub fn lookup_local(&self, sym: Sym) -> Option<Name> { pub fn lookup_local(&self, sym: Sym) -> Option<Name> {
self.locals() self.locals().and_then(|locals| locals.get(&sym)).copied()
.and_then(|locals| locals.get(&sym))
.copied()
} }
pub fn lookup_global(&self, sym: Sym) -> Option<Name> { pub fn lookup_global(&self, sym: Sym) -> Option<Name> {
@@ -23,8 +21,7 @@ impl Scope {
} }
pub fn create_local(&mut self, sym: Sym) -> Name { pub fn create_local(&mut self, sym: Sym) -> Name {
let locals = self.locals_mut() let locals = self.locals_mut().expect("locals");
.expect("locals");
if let Some(local) = locals.get(&sym).copied() { if let Some(local) = locals.get(&sym).copied() {
local local
} else { } else {
@@ -35,8 +32,7 @@ impl Scope {
} }
pub fn create_global(&mut self, sym: Sym) -> Name { pub fn create_global(&mut self, sym: Sym) -> Name {
let globals = self.globals_mut() let globals = self.globals_mut().expect("globals");
.expect("globals");
if let Some(global) = globals.get(&sym).copied() { if let Some(global) = globals.get(&sym).copied() {
global global
} else { } else {

View File

@@ -106,8 +106,7 @@ impl Thunk {
} }
pub fn flatten(self) -> BasicBlockList { pub fn flatten(self) -> BasicBlockList {
Flatten::default() Flatten::default().flatten(self)
.flatten(self)
} }
} }
@@ -158,10 +157,13 @@ impl Flatten {
match thunk { match thunk {
Thunk::Body(thunk) => { Thunk::Body(thunk) => {
let this_block = self.this_block(); let this_block = self.this_block();
let prev = self.blocks.insert(this_block, BasicBlock::Block { let prev = self.blocks.insert(
this_block,
BasicBlock::Block {
exit: next_block, exit: next_block,
block: thunk, block: thunk,
}); },
);
assert!(prev.is_none()); assert!(prev.is_none());
} }
Thunk::List(thunks) => { Thunk::List(thunks) => {
@@ -172,14 +174,20 @@ impl Flatten {
} }
assert_eq!(next_block, self.this_block()); assert_eq!(next_block, self.this_block());
} }
Thunk::Branch { thunk_true, thunk_false, } => { Thunk::Branch {
thunk_true,
thunk_false,
} => {
let branch_block = self.this_block(); let branch_block = self.this_block();
let block_true = self.this_block() + 1; let block_true = self.this_block() + 1;
let block_false = block_true + thunk_true.basic_block_count(); let block_false = block_true + thunk_true.basic_block_count();
self.blocks.insert(branch_block, BasicBlock::Branch { self.blocks.insert(
branch_block,
BasicBlock::Branch {
block_true, block_true,
block_false, block_false,
}); },
);
self.flatten_next(next_block, *thunk_true); self.flatten_next(next_block, *thunk_true);
self.flatten_next(next_block, *thunk_false); self.flatten_next(next_block, *thunk_false);
assert_eq!(self.this_block(), next_block); assert_eq!(self.this_block(), next_block);
@@ -278,7 +286,10 @@ impl Visit for CompileBody<'_> {
if let Some(local) = self.compile.lookup_local(sym) { if let Some(local) = self.compile.lookup_local(sym) {
thunk = Inst::PopLocal(Some(local)).into(); thunk = Inst::PopLocal(Some(local)).into();
} else { } else {
let global = self.compile.lookup_global(sym).expect("name expected to exist someplace(?)"); let global = self
.compile
.lookup_global(sym)
.expect("name expected to exist someplace(?)");
thunk = Inst::PopGlobal(Some(global)).into(); thunk = Inst::PopGlobal(Some(global)).into();
} }
} }
@@ -378,9 +389,7 @@ impl Visit for CompileBody<'_> {
} }
// Compile function body // Compile function body
let mut code = self.visit_body(&expr.body)? let mut code = self.visit_body(&expr.body)?.flatten().to_vec();
.flatten()
.to_vec();
// If the last instruction is not a return, or if there are no instructions, then return // If the last instruction is not a return, or if there are no instructions, then return
// :nil value. // :nil value.
@@ -390,7 +399,9 @@ impl Visit for CompileBody<'_> {
} }
// remap (Sym -> Name) to be (Name -> Sym) and make sure it's all in order. // remap (Sym -> Name) to be (Name -> Sym) and make sure it's all in order.
let scope_locals: BTreeMap<_, _> = self.compile.pop_scope_layer() let scope_locals: BTreeMap<_, _> = self
.compile
.pop_scope_layer()
.unwrap() .unwrap()
.into_iter() .into_iter()
.map(|(sym, name)| (name, sym)) .map(|(sym, name)| (name, sym))
@@ -399,7 +410,8 @@ impl Visit for CompileBody<'_> {
// this should be in numeric order since: // this should be in numeric order since:
// 1. locals are created exactly once or looked up // 1. locals are created exactly once or looked up
// 2. scope_locals is a btreemap, keyed by names, which are in order from 0..N // 2. scope_locals is a btreemap, keyed by names, which are in order from 0..N
let locals: FunLocals = scope_locals.into_iter() let locals: FunLocals = scope_locals
.into_iter()
.enumerate() .enumerate()
.map(|(index, (name, sym))| { .map(|(index, (name, sym))| {
assert_eq!(index, name.index()); assert_eq!(index, name.index());
@@ -407,7 +419,9 @@ impl Visit for CompileBody<'_> {
}) })
.collect(); .collect();
let (hdl, _fun) = self.compile.push_const(UserFun::new_obj(code, locals, expr.params.len())); let (hdl, _fun) =
self.compile
.push_const(UserFun::new_obj(code, locals, expr.params.len()));
// TODO(compile) : determine return value at the end of the body (preferably at parse-time) // TODO(compile) : determine return value at the end of the body (preferably at parse-time)
@@ -427,7 +441,10 @@ impl Visit for CompileBody<'_> {
// This checks to make sure that it's both a local variable and that there's more // This checks to make sure that it's both a local variable and that there's more
// than one scope layer. // than one scope layer.
let sym = global_sym(ident.to_string()); let sym = global_sym(ident.to_string());
if let (true, Some(local)) = (self.compile.scope().layers_len() > 1, self.compile.lookup_local(sym)) { if let (true, Some(local)) = (
self.compile.scope().layers_len() > 1,
self.compile.lookup_local(sym),
) {
// get local // get local
Inst::LoadLocal(local).into() Inst::LoadLocal(local).into()
} else { } else {
@@ -466,25 +483,20 @@ fn test_flatten_thunk() {
let init_body = vec![ let init_body = vec![
Inst::PushSym(Sym::new(0)), Inst::PushSym(Sym::new(0)),
Inst::PushSym(Sym::new(1)), Inst::PushSym(Sym::new(1)),
Inst::Call(1) Inst::Call(1),
]; ];
let true_body = vec![Inst::PushSym(Sym::new(2))]; let true_body = vec![Inst::PushSym(Sym::new(2))];
let false_body = vec![Inst::PushSym(Sym::new(3))]; let false_body = vec![Inst::PushSym(Sym::new(3))];
let end_body = vec![ let end_body = vec![Inst::PushSym(Sym::new(1)), Inst::Call(1)];
Inst::PushSym(Sym::new(1)),
Inst::Call(1)
];
let thunk = Thunk::List(vec![ let thunk = Thunk::List(vec![
// do something before // do something before
Thunk::Body(init_body.clone()), Thunk::Body(init_body.clone()),
// branch // branch
Thunk::Branch { Thunk::Branch {
thunk_true: Thunk::Body(true_body.clone()).into(), thunk_true: Thunk::Body(true_body.clone()).into(),
thunk_false: Thunk::Body(false_body.clone()).into(), thunk_false: Thunk::Body(false_body.clone()).into(),
}, },
// do something after // do something after
Thunk::Body(end_body.clone()), Thunk::Body(end_body.clone()),
]); ]);
@@ -495,10 +507,55 @@ fn test_flatten_thunk() {
assert_eq!(blocks.len(), block_count); assert_eq!(blocks.len(), block_count);
let mut iter = blocks.into_iter(); let mut iter = blocks.into_iter();
assert_eq!(iter.next().unwrap(), (0, BasicBlock::Block { exit: 1, block: init_body, })); assert_eq!(
assert_eq!(iter.next().unwrap(), (1, BasicBlock::Branch { block_true: 2, block_false: 3, })); iter.next().unwrap(),
assert_eq!(iter.next().unwrap(), (2, BasicBlock::Block { exit: 4, block: true_body, })); (
assert_eq!(iter.next().unwrap(), (3, BasicBlock::Block { exit: 4, block: false_body, })); 0,
assert_eq!(iter.next().unwrap(), (4, BasicBlock::Block { exit: 5, block: end_body, })); BasicBlock::Block {
exit: 1,
block: init_body,
}
)
);
assert_eq!(
iter.next().unwrap(),
(
1,
BasicBlock::Branch {
block_true: 2,
block_false: 3,
}
)
);
assert_eq!(
iter.next().unwrap(),
(
2,
BasicBlock::Block {
exit: 4,
block: true_body,
}
)
);
assert_eq!(
iter.next().unwrap(),
(
3,
BasicBlock::Block {
exit: 4,
block: false_body,
}
)
);
assert_eq!(
iter.next().unwrap(),
(
4,
BasicBlock::Block {
exit: 5,
block: end_body,
}
)
);
assert!(iter.next().is_none()); assert!(iter.next().is_none());
} }

View File

@@ -3,6 +3,6 @@
#[macro_use] #[macro_use]
pub mod obj; pub mod obj;
pub mod syn;
pub mod compile; pub mod compile;
pub mod syn;
pub mod vm; pub mod vm;

View File

@@ -1,6 +1,9 @@
use crate::obj::{ObjRef, sym::Sym}; use crate::obj::{sym::Sym, ObjRef};
use shredder::{Gc, Scan}; use shredder::{Gc, Scan};
use std::{collections::BTreeMap, ops::{Deref, DerefMut}}; use std::{
collections::BTreeMap,
ops::{Deref, DerefMut},
};
pub type Attrs = BTreeMap<Sym, ObjRef>; pub type Attrs = BTreeMap<Sym, ObjRef>;
pub type VtableAttrs = Gc<Attrs>; pub type VtableAttrs = Gc<Attrs>;
@@ -12,7 +15,9 @@ pub struct Vtable {
impl Vtable { impl Vtable {
pub fn new(attrs: Attrs) -> Self { pub fn new(attrs: Attrs) -> Self {
Self { attrs: Gc::new(attrs), } Self {
attrs: Gc::new(attrs),
}
} }
} }

View File

@@ -1,49 +1,72 @@
use crate::{obj::{prelude::*, reserved::*}, vm::{error::*, signal::*}}; use crate::{
obj::{prelude::*, reserved::*},
vm::{error::*, signal::*},
};
use maplit::btreemap; use maplit::btreemap;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::collections::BTreeMap; use std::collections::BTreeMap;
pub static PRINTLN_BUILTIN_FUN: Lazy<NativeFunRef> = Lazy::new(|| NativeFun::new_obj(1, |_, vm, args| { pub static PRINTLN_BUILTIN_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
NativeFun::new_obj(1, |_, vm, args| {
// TODO : use __get_attr__ when it gets added // TODO : use __get_attr__ when it gets added
let to_string = { let to_string = {
let obj_ref = &args[0]; let obj_ref = &args[0];
read_obj!(let obj = obj_ref); read_obj!(let obj = obj_ref);
obj.get_attr(STR_MEMBER_NAME.sym) obj.get_attr(STR_MEMBER_NAME.sym)
.ok_or(Error::MissingAttr { attr: STR_MEMBER_NAME.sym })? .ok_or(Error::MissingAttr {
attr: STR_MEMBER_NAME.sym,
})?
}; };
let return_value = vm.call(to_string, vec![])?; let return_value = vm.call(to_string, vec![])?;
{ {
read_obj!(let str_obj = return_value); read_obj!(let str_obj = return_value);
let str_obj: &Str = str_obj.as_any().downcast_ref() let str_obj: &Str =
.ok_or_else(|| Error::ValueError { error: "expected str value".to_string(), })?; str_obj
.as_any()
.downcast_ref()
.ok_or_else(|| Error::ValueError {
error: "expected str value".to_string(),
})?;
println!("{}", str_obj.value()); println!("{}", str_obj.value());
} }
vm.push(NIL_NAME.sym_ref()); vm.push(NIL_NAME.sym_ref());
Ok(Signal::Return) Ok(Signal::Return)
})); })
});
pub static PRINT_BUILTIN_FUN: Lazy<NativeFunRef> = Lazy::new(|| NativeFun::new_obj(1, |_, vm, args| { pub static PRINT_BUILTIN_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
NativeFun::new_obj(1, |_, vm, args| {
// TODO : use __get_attr__ when it gets added // TODO : use __get_attr__ when it gets added
let to_string = { let to_string = {
let obj_ref = &args[0]; let obj_ref = &args[0];
read_obj!(let obj = obj_ref); read_obj!(let obj = obj_ref);
obj.get_attr(STR_MEMBER_NAME.sym) obj.get_attr(STR_MEMBER_NAME.sym)
.ok_or(Error::MissingAttr { attr: STR_MEMBER_NAME.sym })? .ok_or(Error::MissingAttr {
attr: STR_MEMBER_NAME.sym,
})?
}; };
let return_value = vm.call(to_string, vec![])?; let return_value = vm.call(to_string, vec![])?;
{ {
read_obj!(let str_obj = return_value); read_obj!(let str_obj = return_value);
let str_obj: &Str = str_obj.as_any().downcast_ref() let str_obj: &Str =
.ok_or_else(|| Error::ValueError { error: "expected str value".to_string(), })?; str_obj
.as_any()
.downcast_ref()
.ok_or_else(|| Error::ValueError {
error: "expected str value".to_string(),
})?;
print!("{}", str_obj.value()); print!("{}", str_obj.value());
} }
vm.push(NIL_NAME.sym_ref()); vm.push(NIL_NAME.sym_ref());
Ok(Signal::Return) Ok(Signal::Return)
})); })
});
pub static BUILTIN_OBJS: Lazy<BTreeMap<Sym, ObjRef>> = Lazy::new(|| btreemap! { pub static BUILTIN_OBJS: Lazy<BTreeMap<Sym, ObjRef>> = Lazy::new(|| {
btreemap! {
PRINTLN_BUILTIN_NAME.sym => PRINTLN_BUILTIN_FUN.clone() as _, PRINTLN_BUILTIN_NAME.sym => PRINTLN_BUILTIN_FUN.clone() as _,
PRINT_BUILTIN_NAME.sym => PRINT_BUILTIN_FUN.clone() as _, PRINT_BUILTIN_NAME.sym => PRINT_BUILTIN_FUN.clone() as _,
}
}); });

View File

@@ -1,7 +1,14 @@
use crate::{obj::{reserved::*, prelude::*}, vm::{consts::ConstPool, error::*, frame::*, inst::Inst, signal::*, Vm}}; use crate::{
obj::{prelude::*, reserved::*},
vm::{consts::ConstPool, error::*, frame::*, inst::Inst, signal::*, Vm},
};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use shredder::{GcSafeWrapper, Scan}; use shredder::{GcSafeWrapper, Scan};
use std::{fmt::{Debug, Formatter, self}, io::{self, Write}, sync::Arc}; use std::{
fmt::{self, Debug, Formatter},
io::{self, Write},
sync::Arc,
};
pub type FunLocals = Vec<Sym>; pub type FunLocals = Vec<Sym>;
@@ -49,9 +56,13 @@ impl Obj for Method {
Some(&mut self.attrs) Some(&mut self.attrs)
} }
fn as_any(&self) -> &dyn std::any::Any { self } fn as_any(&self) -> &dyn std::any::Any {
self
}
fn as_fun(&self) -> Option<&dyn Fun> { Some(self) } fn as_fun(&self) -> Option<&dyn Fun> {
Some(self)
}
} }
impl Fun for Method { impl Fun for Method {
@@ -110,7 +121,12 @@ impl UserFun {
&self.locals &self.locals
} }
pub fn dump(&self, writer: &mut dyn Write, const_pool: &ConstPool, globals: &FunLocals) -> io::Result<()> { pub fn dump(
&self,
writer: &mut dyn Write,
const_pool: &ConstPool,
globals: &FunLocals,
) -> io::Result<()> {
fn num_digits(n: usize, radix: usize) -> usize { fn num_digits(n: usize, radix: usize) -> usize {
((n as f64) + 1.0).log(radix as f64).ceil() as usize ((n as f64) + 1.0).log(radix as f64).ceil() as usize
} }
@@ -126,21 +142,22 @@ impl UserFun {
sym.index().to_string(), sym.index().to_string(),
global_sym_lookup(*sym).unwrap().to_string(), global_sym_lookup(*sym).unwrap().to_string(),
), ),
Inst::PushConst(hdl) => ( Inst::PushConst(hdl) => (hdl.index().to_string(), {
hdl.index().to_string(),
{
let obj_ref = const_pool.get(*hdl); let obj_ref = const_pool.get(*hdl);
read_obj!(let obj = obj_ref); read_obj!(let obj = obj_ref);
format!("{:?}", obj) format!("{:?}", obj)
}, }),
),
Inst::LoadLocal(local) => ( Inst::LoadLocal(local) => (
local.index().to_string(), local.index().to_string(),
global_sym_lookup(self.locals()[local.index()]).unwrap().to_string(), global_sym_lookup(self.locals()[local.index()])
.unwrap()
.to_string(),
), ),
Inst::LoadGlobal(global) => ( Inst::LoadGlobal(global) => (
global.index().to_string(), global.index().to_string(),
global_sym_lookup(globals[global.index()]).unwrap().to_string(), global_sym_lookup(globals[global.index()])
.unwrap()
.to_string(),
), ),
Inst::PopLocal(local) => { Inst::PopLocal(local) => {
if let Some(local) = local { if let Some(local) = local {
@@ -162,14 +179,8 @@ impl UserFun {
("(discarded)".to_string(), String::new()) ("(discarded)".to_string(), String::new())
} }
} }
Inst::Jump(addr) | Inst::JumpTrue(addr) => ( Inst::Jump(addr) | Inst::JumpTrue(addr) => (addr.to_string(), String::new()),
addr.to_string(), Inst::Call(argc) => (argc.to_string(), String::new()),
String::new(),
),
Inst::Call(argc) => (
argc.to_string(),
String::new(),
),
_ => (String::new(), String::new()), _ => (String::new(), String::new()),
}; };
@@ -224,12 +235,13 @@ impl Fun for UserFun {
got: args.len(), got: args.len(),
}); });
} }
let bindings: FrameBindings = args.into_iter() let bindings: FrameBindings = args.into_iter().enumerate().collect();
.enumerate() Ok(Frame::User(UserFrame::new(
.collect(); callee,
Ok(Frame::User( bindings,
UserFrame::new(callee, bindings, vm.pc(), Arc::clone(&self.code)) vm.pc(),
)) Arc::clone(&self.code),
)))
} }
} }
@@ -294,7 +306,10 @@ impl NativeFun {
impl Debug for NativeFun { impl Debug for NativeFun {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_struct("NativeFun") fmt.debug_struct("NativeFun")
.field("fun", &format!("(function at {:x})", &self.fun as *const _ as usize)) .field(
"fun",
&format!("(function at {:x})", &self.fun as *const _ as usize),
)
.field("attrs", &self.attrs) .field("attrs", &self.attrs)
.finish() .finish()
} }
@@ -330,9 +345,7 @@ impl Fun for NativeFun {
got: args.len(), got: args.len(),
}); });
} }
Ok(Frame::Native( Ok(Frame::Native(NativeFrame::new(callee, *self.fun, args)))
NativeFrame::new(callee, *self.fun, args)
))
} }
} }

View File

@@ -1,7 +1,10 @@
use crate::{obj::{prelude::*, reserved::*}, vm::error::*}; use crate::{
obj::{prelude::*, reserved::*},
vm::error::*,
};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use shredder::Scan; use shredder::Scan;
use std::fmt::{Debug, Formatter, self}; use std::fmt::{self, Debug, Formatter};
pub type IntRef = ObjRef<Int>; pub type IntRef = ObjRef<Int>;
pub type IntValue = i128; pub type IntValue = i128;
@@ -43,9 +46,7 @@ impl_obj_readonly!(Int);
impl Debug for Int { impl Debug for Int {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_struct("Int") fmt.debug_struct("Int").field("value", &self.value).finish()
.field("value", &self.value)
.finish()
} }
} }

View File

@@ -9,14 +9,12 @@ pub struct Interner<T: Hash + Eq> {
impl<T: Hash + Eq> Interner<T> { impl<T: Hash + Eq> Interner<T> {
pub fn new(forward: Vec<Arc<T>>) -> Self { pub fn new(forward: Vec<Arc<T>>) -> Self {
let reverse = forward.iter() let reverse = forward
.iter()
.enumerate() .enumerate()
.map(|(i, s)| (Arc::clone(s), Sym::new(i))) .map(|(i, s)| (Arc::clone(s), Sym::new(i)))
.collect(); .collect();
Self { Self { forward, reverse }
forward,
reverse,
}
} }
pub fn forward(&self) -> &Vec<Arc<T>> { pub fn forward(&self) -> &Vec<Arc<T>> {
@@ -41,18 +39,19 @@ impl<T: Hash + Eq> Interner<T> {
} }
pub fn lookup(&self, sym: Sym) -> Option<Arc<T>> { pub fn lookup(&self, sym: Sym) -> Option<Arc<T>> {
self.forward.get(sym.index()) self.forward.get(sym.index()).map(Arc::clone)
.map(Arc::clone)
} }
pub fn lookup_sym(&self, value: impl std::borrow::Borrow<T>) -> Option<Sym> { pub fn lookup_sym(&self, value: impl std::borrow::Borrow<T>) -> Option<Sym> {
self.reverse.get(value.borrow()) self.reverse.get(value.borrow()).copied()
.copied()
} }
} }
impl<T: Hash + Eq> Default for Interner<T> { impl<T: Hash + Eq> Default for Interner<T> {
fn default() -> Self { fn default() -> Self {
Interner { forward: Default::default(), reverse: Default::default(), } Interner {
forward: Default::default(),
reverse: Default::default(),
}
} }
} }

View File

@@ -23,7 +23,7 @@ macro_rules! impl_obj {
($ty:ty) => { ($ty:ty) => {
impl_obj!($ty, vtable, attrs); impl_obj!($ty, vtable, attrs);
} };
} }
#[macro_export] #[macro_export]

View File

@@ -40,7 +40,7 @@ macro_rules! obj_attr {
fn $name(&self) -> Option<ObjRef> { fn $name(&self) -> Option<ObjRef> {
self.get_attr($attr.sym) self.get_attr($attr.sym)
} }
} };
} }
pub trait Obj: Scan + Debug { pub trait Obj: Scan + Debug {
@@ -58,7 +58,9 @@ pub trait Obj: Scan + Debug {
fn as_any(&self) -> &dyn std::any::Any; fn as_any(&self) -> &dyn std::any::Any;
/// Gets this object as a `dyn Fun` reference. /// Gets this object as a `dyn Fun` reference.
fn as_fun(&self) -> Option<&dyn Fun> { None } fn as_fun(&self) -> Option<&dyn Fun> {
None
}
obj_attr!(get_ty, TY_MEMBER_NAME); obj_attr!(get_ty, TY_MEMBER_NAME);
obj_attr!(get_call, CALL_MEMBER_NAME); obj_attr!(get_call, CALL_MEMBER_NAME);
@@ -140,7 +142,8 @@ where
// impl Debug for ObjRef // impl Debug for ObjRef
// //
impl<T> Debug for ObjRef<T> impl<T> Debug for ObjRef<T>
where T: Obj + ?Sized + Send + Sync + 'static, where
T: Obj + ?Sized + Send + Sync + 'static,
{ {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
read_obj!(let obj: &T = self); read_obj!(let obj: &T = self);

View File

@@ -1,6 +1,6 @@
//! Reserved names for object members. //! Reserved names for object members.
use crate::obj::sym::{Sym, SymRef, global_sym, global_sym_ref}; use crate::obj::sym::{global_sym, global_sym_ref, Sym, SymRef};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
macro_rules! name { macro_rules! name {
@@ -8,9 +8,9 @@ macro_rules! name {
pub static $name: Lazy<NameInfo> = Lazy::new(|| { pub static $name: Lazy<NameInfo> = Lazy::new(|| {
let name = $text; let name = $text;
let sym = global_sym(name.to_string()); let sym = global_sym(name.to_string());
NameInfo { name, sym, } NameInfo { name, sym }
}); });
} };
} }
pub struct NameInfo { pub struct NameInfo {
@@ -79,4 +79,3 @@ name!(PLUS_OP_NAME, "__add__");
name!(MINUS_OP_NAME, "__sub__"); name!(MINUS_OP_NAME, "__sub__");
name!(TIMES_OP_NAME, "__mul__"); name!(TIMES_OP_NAME, "__mul__");
name!(DIV_OP_NAME, "__div__"); name!(DIV_OP_NAME, "__div__");

View File

@@ -1,7 +1,10 @@
use crate::{obj::{prelude::*, reserved::*}, vm::error::*}; use crate::{
obj::{prelude::*, reserved::*},
vm::error::*,
};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use shredder::Scan; use shredder::Scan;
use std::fmt::{Debug, Formatter, self}; use std::fmt::{self, Debug, Formatter};
pub type StrRef = ObjRef<Str>; pub type StrRef = ObjRef<Str>;
@@ -37,9 +40,7 @@ impl_obj_readonly!(Str);
impl Debug for Str { impl Debug for Str {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_struct("Str") fmt.debug_struct("Str").field("value", &self.value).finish()
.field("value", &self.value)
.finish()
} }
} }
@@ -86,8 +87,9 @@ static STR_INT_FUN: Lazy<NativeFunRef> = Lazy::new(|| {
error: "expected Str value".to_string(), error: "expected Str value".to_string(),
})?; })?;
let int: IntValue = str_obj.value.parse() let int: IntValue = str_obj.value.parse().map_err(|_| Error::ValueError {
.map_err(|_| Error::ValueError { error: "invalid Int value".to_string(), })?; error: "invalid Int value".to_string(),
})?;
vm.push(Int::new_obj(int)); vm.push(Int::new_obj(int));
Ok(crate::vm::signal::Signal::Return) Ok(crate::vm::signal::Signal::Return)

View File

@@ -1,6 +1,9 @@
use crate::obj::{intern::Interner, reserved::*, prelude::*}; use crate::obj::{intern::Interner, prelude::*, reserved::*};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use std::{collections::BTreeMap, sync::{Arc, Mutex}}; use std::{
collections::BTreeMap,
sync::{Arc, Mutex},
};
// //
// struct Sym // struct Sym

View File

@@ -1,4 +1,4 @@
use crate::obj::{reserved::*, prelude::*}; use crate::obj::{prelude::*, reserved::*};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use shredder::Scan; use shredder::Scan;

View File

@@ -15,8 +15,7 @@ impl<V: Visit> Accept<V> for Body {
impl<V: Visit<Out = ()>> DefaultAccept<V> for Body { impl<V: Visit<Out = ()>> DefaultAccept<V> for Body {
fn default_accept(&self, visitor: &mut V) -> V::Out { fn default_accept(&self, visitor: &mut V) -> V::Out {
self.iter() self.iter().for_each(|stmt| visitor.visit_stmt(stmt));
.for_each(|stmt| visitor.visit_stmt(stmt));
} }
} }
@@ -96,7 +95,7 @@ impl<V: Visit<Out=()>> DefaultAccept<V> for LhsExpr {
fn default_accept(&self, visitor: &mut V) -> V::Out { fn default_accept(&self, visitor: &mut V) -> V::Out {
match self { match self {
LhsExpr::SetAttr(a) => a.accept(visitor), LhsExpr::SetAttr(a) => a.accept(visitor),
LhsExpr::Name(_) => {}, LhsExpr::Name(_) => {}
} }
} }
} }
@@ -123,7 +122,6 @@ impl<V: Visit<Out=()>> DefaultAccept<V> for ReturnStmt {
} }
} }
// //
// struct Expr // struct Expr
// //
@@ -237,7 +235,7 @@ pub struct BinExpr {
impl BinExpr { impl BinExpr {
pub fn new_expr(lhs: Expr, op: BinOp, rhs: Expr) -> Expr { pub fn new_expr(lhs: Expr, op: BinOp, rhs: Expr) -> Expr {
Self { lhs, op, rhs, }.into() Self { lhs, op, rhs }.into()
} }
} }
@@ -329,8 +327,7 @@ impl<V: Visit> Accept<V> for CallExpr {
impl<V: Visit<Out = ()>> DefaultAccept<V> for CallExpr { impl<V: Visit<Out = ()>> DefaultAccept<V> for CallExpr {
fn default_accept(&self, visitor: &mut V) -> V::Out { fn default_accept(&self, visitor: &mut V) -> V::Out {
visitor.visit_expr(&self.expr); visitor.visit_expr(&self.expr);
self.args.iter() self.args.iter().for_each(|arg| visitor.visit_expr(arg));
.for_each(|arg| visitor.visit_expr(arg));
} }
} }
@@ -345,7 +342,7 @@ pub struct IndexExpr {
impl IndexExpr { impl IndexExpr {
pub fn new_expr(expr: Expr, index: Expr) -> Expr { pub fn new_expr(expr: Expr, index: Expr) -> Expr {
Self { expr, index, }.into() Self { expr, index }.into()
} }
} }
@@ -379,7 +376,7 @@ pub struct AccessExpr {
impl AccessExpr { impl AccessExpr {
pub fn new_expr(expr: Expr, access: String) -> Expr { pub fn new_expr(expr: Expr, access: String) -> Expr {
Self { expr, access, }.into() Self { expr, access }.into()
} }
} }
@@ -415,7 +412,7 @@ pub struct FunExpr {
// //
impl FunExpr { impl FunExpr {
pub fn new_expr(params: Vec<String>, body: Body) -> Expr { pub fn new_expr(params: Vec<String>, body: Body) -> Expr {
Self { params, body, }.into() Self { params, body }.into()
} }
} }
@@ -473,9 +470,10 @@ pub fn parse(text: &str) -> Result<Option<Vec<Stmt>>, Vec<String>> {
let (res, errors) = parser::parse(&lexer); let (res, errors) = parser::parse(&lexer);
if !errors.is_empty() { if !errors.is_empty() {
return Err(errors.into_iter() return Err(errors
.into_iter()
.map(|e| e.pp(&lexer, &parser::token_epp)) .map(|e| e.pp(&lexer, &parser::token_epp))
.collect()) .collect());
} }
Ok(res.transpose().unwrap()) Ok(res.transpose().unwrap())

View File

@@ -1,18 +1,18 @@
#![macro_use] mod macros; #![macro_use]
pub mod ast; pub mod ast;
mod macros;
pub mod visit; pub mod visit;
pub mod lexer { pub mod lexer {
lrlex_mod!("syn/lexer.l"); lrlex_mod!("syn/lexer.l");
use lrlex::lrlex_mod;
pub use self::lexer_l::*; pub use self::lexer_l::*;
use lrlex::lrlex_mod;
} }
pub mod parser { pub mod parser {
lrpar_mod!("syn/parser.y"); lrpar_mod!("syn/parser.y");
use lrpar::lrpar_mod;
pub use self::parser_y::*; pub use self::parser_y::*;
use lrpar::lrpar_mod;
} }
//pub use lexer_l as lexer; //pub use lexer_l as lexer;

View File

@@ -4,20 +4,17 @@ use snafu::Snafu;
#[derive(Debug, Snafu)] #[derive(Debug, Snafu)]
pub enum Error { pub enum Error {
#[snafu(display("missing attribute: {}", global_sym_lookup(*attr).unwrap()))] #[snafu(display("missing attribute: {}", global_sym_lookup(*attr).unwrap()))]
MissingAttr { MissingAttr { attr: Sym },
attr: Sym,
},
#[snafu(display("{}", error))] #[snafu(display("{}", error))]
ValueError { ValueError { error: String },
error: String,
},
#[snafu(display("incorrect function arity; expected {} but got {} instead", expected, got))] #[snafu(display(
ArityError { "incorrect function arity; expected {} but got {} instead",
expected: usize, expected,
got: usize, got
}, ))]
ArityError { expected: usize, got: usize },
} }
pub type Result<T, E = Error> = std::result::Result<T, E>; pub type Result<T, E = Error> = std::result::Result<T, E>;

View File

@@ -1,6 +1,6 @@
use crate::{obj::prelude::*, vm::inst::Inst}; use crate::{obj::prelude::*, vm::inst::Inst};
use std::fmt::{self, Debug, Formatter};
use std::{collections::BTreeMap, sync::Arc}; use std::{collections::BTreeMap, sync::Arc};
use std::fmt::{self, Formatter, Debug};
pub type FrameBindings = BTreeMap<usize, ObjRef>; pub type FrameBindings = BTreeMap<usize, ObjRef>;
@@ -53,8 +53,18 @@ pub struct UserFrame {
} }
impl UserFrame { impl UserFrame {
pub fn new(callee: ObjRef, bindings: FrameBindings, last_pc: usize, code: Arc<Vec<Inst>>) -> Self { pub fn new(
Self { callee, bindings, last_pc, code, } callee: ObjRef,
bindings: FrameBindings,
last_pc: usize,
code: Arc<Vec<Inst>>,
) -> Self {
Self {
callee,
bindings,
last_pc,
code,
}
} }
pub fn bindings(&self) -> &FrameBindings { pub fn bindings(&self) -> &FrameBindings {
@@ -86,7 +96,11 @@ pub struct NativeFrame {
impl NativeFrame { impl NativeFrame {
pub fn new(callee: ObjRef, fun_ptr: NativeFunPtr, args: Vec<ObjRef>) -> Self { pub fn new(callee: ObjRef, fun_ptr: NativeFunPtr, args: Vec<ObjRef>) -> Self {
Self { callee, fun_ptr, args } Self {
callee,
fun_ptr,
args,
}
} }
pub fn fun_ptr(&self) -> &NativeFunPtr { pub fn fun_ptr(&self) -> &NativeFunPtr {
@@ -105,7 +119,10 @@ impl NativeFrame {
impl Debug for NativeFrame { impl Debug for NativeFrame {
fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
fmt.debug_struct("NativeFrame") fmt.debug_struct("NativeFrame")
.field("fun_ptr", &format!("{:#x}", &self.fun_ptr as *const _ as usize)) .field(
"fun_ptr",
&format!("{:#x}", &self.fun_ptr as *const _ as usize),
)
.finish() .finish()
} }
} }

View File

@@ -5,7 +5,7 @@ pub mod inst;
pub mod signal; pub mod signal;
use crate::{ use crate::{
obj::{builtin::BUILTIN_OBJS, reserved::*, prelude::*}, obj::{builtin::BUILTIN_OBJS, prelude::*, reserved::*},
vm::{consts::ConstPool, error::*, frame::*, inst::*, signal::*}, vm::{consts::ConstPool, error::*, frame::*, inst::*, signal::*},
}; };
@@ -19,7 +19,7 @@ pub struct Vm<'c> {
} }
impl<'c> Vm<'c> { impl<'c> Vm<'c> {
pub fn new(const_pool: &'c ConstPool,) -> Self { pub fn new(const_pool: &'c ConstPool) -> Self {
Self { Self {
stack: Default::default(), stack: Default::default(),
frames: vec![], frames: vec![],
@@ -122,9 +122,7 @@ impl<'c> Vm<'c> {
let args = fun.args().clone(); let args = fun.args().clone();
(*fun.fun_ptr())(callee, self, args)? (*fun.fun_ptr())(callee, self, args)?
} }
Frame::User(_) => { Frame::User(_) => self.resume_user_fun(),
self.resume_user_fun()
}
}; };
self.handle_signal(signal)?; self.handle_signal(signal)?;
} }
@@ -148,8 +146,11 @@ impl<'c> Vm<'c> {
match signal { match signal {
Signal::Call(callee, args) => { Signal::Call(callee, args) => {
read_obj!(let callee_obj = callee); read_obj!(let callee_obj = callee);
let frame = callee_obj.as_fun() let frame = callee_obj
.ok_or_else(|| Error::ValueError { error: "cannot call this object".to_string() })? .as_fun()
.ok_or_else(|| Error::ValueError {
error: "cannot call this object".to_string(),
})?
.create_frame(callee.clone(), self, args)?; .create_frame(callee.clone(), self, args)?;
// Jump to the first address of the new function call if it's a user function // Jump to the first address of the new function call if it's a user function
if let Frame::User(_) = &frame { if let Frame::User(_) = &frame {
@@ -207,19 +208,20 @@ impl<'c> Vm<'c> {
self.push(obj_ref); self.push(obj_ref);
} }
Inst::LoadLocal(local) => { Inst::LoadLocal(local) => {
let value = self.get_local(local) let value = self
.get_local(local)
.expect("TODO: throw error for missing local"); .expect("TODO: throw error for missing local");
self.push(value); self.push(value);
} }
Inst::LoadGlobal(global) => { Inst::LoadGlobal(global) => {
let value = self.get_global(global) let value = self
.get_global(global)
.or_else(|| self.get_builtin(global)) .or_else(|| self.get_builtin(global))
.expect("TODO: throw error for missing global"); .expect("TODO: throw error for missing global");
self.push(value); self.push(value);
} }
Inst::PopLocal(name) => { Inst::PopLocal(name) => {
let tos = self.pop() let tos = self.pop().expect("stack underflow");
.expect("stack underflow");
// pop into name // pop into name
if let Some(name) = name { if let Some(name) = name {
self.set_local(name, tos); self.set_local(name, tos);
@@ -227,8 +229,7 @@ impl<'c> Vm<'c> {
// else discard // else discard
} }
Inst::PopGlobal(name) => { Inst::PopGlobal(name) => {
let tos = self.pop() let tos = self.pop().expect("stack underflow");
.expect("stack underflow");
// pop into name // pop into name
if let Some(name) = name { if let Some(name) = name {
self.set_global(name, tos); self.set_global(name, tos);
@@ -244,10 +245,8 @@ impl<'c> Vm<'c> {
self.push(attr); self.push(attr);
} }
Inst::SetAttr(sym) => { Inst::SetAttr(sym) => {
let target = self.pop() let target = self.pop().expect("no target available for SetAttr");
.expect("no target available for SetAttr"); let source = self.pop().expect("no source available for SetAttr");
let source = self.pop()
.expect("no source available for SetAttr");
write_obj!(let target = target); write_obj!(let target = target);
if let Some(attrs) = target.attrs_mut() { if let Some(attrs) = target.attrs_mut() {
attrs.insert(sym, source); attrs.insert(sym, source);
@@ -266,15 +265,17 @@ impl<'c> Vm<'c> {
Inst::Call(argc) => { Inst::Call(argc) => {
let stack_top = self.stack.len() - argc; let stack_top = self.stack.len() - argc;
let args = self.stack.split_off(stack_top); let args = self.stack.split_off(stack_top);
let tos = self.pop() let tos = self.pop().expect("stack underflow");
.expect("stack underflow");
read_obj!(let tos = tos); read_obj!(let tos = tos);
let callee = tos.get_call() let callee = tos
.get_call()
.expect("TODO: throw an error for missing __call__ attr"); .expect("TODO: throw an error for missing __call__ attr");
signal = Some(Signal::Call(callee, args)); signal = Some(Signal::Call(callee, args));
} }
Inst::Index => todo!(), Inst::Index => todo!(),
Inst::Return => { signal = Some(Signal::Return); } Inst::Return => {
signal = Some(Signal::Return);
}
Inst::UnNeg => todo!(), Inst::UnNeg => todo!(),
Inst::UnPos => todo!(), Inst::UnPos => todo!(),
Inst::BinPlus => { Inst::BinPlus => {
@@ -282,7 +283,8 @@ impl<'c> Vm<'c> {
let lhs = self.pop().unwrap(); let lhs = self.pop().unwrap();
let fun = { let fun = {
read_obj!(let lhs = lhs); read_obj!(let lhs = lhs);
lhs.get_plus().expect("TODO: throw an error for missing __add__ attr") lhs.get_plus()
.expect("TODO: throw an error for missing __add__ attr")
}; };
signal = Some(Signal::Call(fun, vec![rhs])); signal = Some(Signal::Call(fun, vec![rhs]));
} }
@@ -291,7 +293,8 @@ impl<'c> Vm<'c> {
let lhs = self.pop().unwrap(); let lhs = self.pop().unwrap();
let fun = { let fun = {
read_obj!(let lhs = lhs); read_obj!(let lhs = lhs);
lhs.get_minus().expect("TODO: throw an error for missing __sub__ attr") lhs.get_minus()
.expect("TODO: throw an error for missing __sub__ attr")
}; };
signal = Some(Signal::Call(fun, vec![rhs])); signal = Some(Signal::Call(fun, vec![rhs]));
} }
@@ -300,7 +303,8 @@ impl<'c> Vm<'c> {
let lhs = self.pop().unwrap(); let lhs = self.pop().unwrap();
let fun = { let fun = {
read_obj!(let lhs = lhs); read_obj!(let lhs = lhs);
lhs.get_mul().expect("TODO: throw an error for missing __mul__ attr") lhs.get_mul()
.expect("TODO: throw an error for missing __mul__ attr")
}; };
signal = Some(Signal::Call(fun, vec![rhs])); signal = Some(Signal::Call(fun, vec![rhs]));
} }
@@ -309,7 +313,8 @@ impl<'c> Vm<'c> {
let lhs = self.pop().unwrap(); let lhs = self.pop().unwrap();
let fun = { let fun = {
read_obj!(let lhs = lhs); read_obj!(let lhs = lhs);
lhs.get_div().expect("TODO: throw an error for missing __div__ attr") lhs.get_div()
.expect("TODO: throw an error for missing __div__ attr")
}; };
signal = Some(Signal::Call(fun, vec![rhs])); signal = Some(Signal::Call(fun, vec![rhs]));
} }
@@ -318,7 +323,8 @@ impl<'c> Vm<'c> {
let lhs = self.pop().unwrap(); let lhs = self.pop().unwrap();
let fun = { let fun = {
read_obj!(let lhs = lhs); read_obj!(let lhs = lhs);
lhs.get_eq().expect("TODO: throw an error for missing __eq__ attr") lhs.get_eq()
.expect("TODO: throw an error for missing __eq__ attr")
}; };
signal = Some(Signal::Call(fun, vec![rhs])); signal = Some(Signal::Call(fun, vec![rhs]));
} }
@@ -363,7 +369,8 @@ impl<'c> Vm<'c> {
} }
fn set_global(&mut self, name: Name, value: ObjRef) { fn set_global(&mut self, name: Name, value: ObjRef) {
let frame = self.frames_mut() let frame = self
.frames_mut()
.first_mut() .first_mut()
.expect("global stack frame") .expect("global stack frame")
.user_frame_mut() .user_frame_mut()

View File

@@ -6,4 +6,3 @@ pub enum Signal {
Call(ObjRef, Vec<ObjRef>), Call(ObjRef, Vec<ObjRef>),
Return, Return,
} }