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:
2022-01-16 16:49:54 -08:00
parent 67054b2c84
commit 1eb7eb73cb
6 changed files with 64 additions and 85 deletions

View File

@@ -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,