Remove RuntimeSpanError and just incorporate it into RuntimeError; add Span information to compiled instructions
* RuntimeSpanError was an extraneous solution to adding spans to the errors; so instead this behavior has been delegated to the RuntimeError itself. * Usage of Inst has mostly been replaced with SpInst so if an error is encountered, we can spit out where it happened in the source code (hopefully with a stack trace). Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -17,7 +17,7 @@ impl<'s> Compile<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compile(&mut self, stmt_list: Vec<SpStmt>) -> Vec<Inst> {
|
||||
pub fn compile(&mut self, stmt_list: Vec<SpStmt>) -> Vec<SpInst> {
|
||||
// Compile meta-statements
|
||||
let expr_list = self.compile_meta(stmt_list);
|
||||
self.compile_expr_list(&expr_list)
|
||||
@@ -42,7 +42,7 @@ impl<'s> Compile<'s> {
|
||||
todo!("includes")
|
||||
}
|
||||
|
||||
fn compile_expr_list(&mut self, expr_list: &Vec<SpExpr>) -> Vec<Inst> {
|
||||
fn compile_expr_list(&mut self, expr_list: &Vec<SpExpr>) -> Vec<SpInst> {
|
||||
// Scoping is done here.
|
||||
// Local scopes are implicit. If a variable is assigned to at
|
||||
// all in the current scope, it's considered to be a local.
|
||||
@@ -67,19 +67,20 @@ impl<'s> Compile<'s> {
|
||||
let quote =
|
||||
self.quote_table
|
||||
.insert(expr.span().clone(), locals, stmts.clone(), compiled);
|
||||
Inst::PushValue(Value::Quote(quote)).into()
|
||||
let inst = Inst::PushValue(Value::Quote(quote));
|
||||
SpInst::new(expr.span().clone(), inst).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compile_atom(&mut self, atom: &SpAtom) -> Thunk {
|
||||
match atom.inner() {
|
||||
Atom::Float(f) => Inst::PushValue(Value::Float(*f)).into(),
|
||||
Atom::Int(i) => Inst::PushValue(Value::Int(*i)).into(),
|
||||
Atom::Str(s) => Inst::PushValue(Value::Str(s.clone())).into(),
|
||||
let inst = match atom.inner() {
|
||||
Atom::Float(f) => Inst::PushValue(Value::Float(*f)),
|
||||
Atom::Int(i) => Inst::PushValue(Value::Int(*i)),
|
||||
Atom::Str(s) => Inst::PushValue(Value::Str(s.clone())),
|
||||
Atom::Assign(text) => {
|
||||
let word = self.scope_stack.insert_local(text);
|
||||
Inst::Store(word).into()
|
||||
Inst::Store(word)
|
||||
}
|
||||
Atom::Word(text) => {
|
||||
// Look for locally defined symbols first. One can't be found,
|
||||
@@ -90,10 +91,11 @@ impl<'s> Compile<'s> {
|
||||
} else {
|
||||
self.scope_stack.insert_local(text)
|
||||
};
|
||||
Inst::Load(word).into()
|
||||
Inst::Load(word)
|
||||
}
|
||||
Atom::Apply => Inst::Call.into(),
|
||||
}
|
||||
Atom::Apply => Inst::Call,
|
||||
};
|
||||
SpInst::new(atom.span().clone(), inst).into()
|
||||
}
|
||||
|
||||
/// Discovers and inserts local variables into the scope.
|
||||
@@ -111,18 +113,18 @@ impl<'s> Compile<'s> {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Thunk {
|
||||
Block(Vec<Inst>),
|
||||
Block(Vec<SpInst>),
|
||||
List(Vec<Thunk>),
|
||||
}
|
||||
|
||||
impl From<Inst> for Thunk {
|
||||
fn from(inst: Inst) -> Thunk {
|
||||
impl From<SpInst> for Thunk {
|
||||
fn from(inst: SpInst) -> Thunk {
|
||||
Thunk::Block(vec![inst])
|
||||
}
|
||||
}
|
||||
|
||||
impl Thunk {
|
||||
fn flatten(self) -> Vec<Inst> {
|
||||
fn flatten(self) -> Vec<SpInst> {
|
||||
use Thunk::*;
|
||||
match self {
|
||||
Block(block) => block,
|
||||
|
||||
Reference in New Issue
Block a user