assignment: Add variable assignment
* Syntax for x = y * Compiler creates Inst::Store thunks * New Vm::store function Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
println(123);
|
||||
println(None);
|
||||
println("hell world");
|
||||
message = "hell world";
|
||||
println(message);
|
||||
|
||||
@@ -37,7 +37,17 @@ impl Compiler {
|
||||
|
||||
fn emit_stmt(&mut self, stmt: &SpStmt) -> Thunk {
|
||||
match stmt.inner() {
|
||||
Stmt::Assign(_lhs_expr, _expr) => todo!(),
|
||||
Stmt::Assign(lhs_expr, expr) => match lhs_expr.inner() {
|
||||
AssignLhs::Name(n) => {
|
||||
let name = self.scope().lookup_scoped(n).unwrap();
|
||||
let mut thunk = self.emit_expr(expr);
|
||||
thunk.push(Inst::Store(name));
|
||||
thunk
|
||||
}
|
||||
AssignLhs::Complex(_, _) => {
|
||||
todo!("Complex LHS foo.bar assign")
|
||||
}
|
||||
},
|
||||
Stmt::Expr(expr) => {
|
||||
let mut thunk = self.emit_expr(expr);
|
||||
thunk.push(Inst::Pop);
|
||||
@@ -91,7 +101,7 @@ impl Compiler {
|
||||
fn gather_names(&mut self, stmts: &Vec<SpStmt>) {
|
||||
for stmt in stmts {
|
||||
match stmt.inner() {
|
||||
Stmt::Assign(lhs, _) => match lhs {
|
||||
Stmt::Assign(lhs, _) => match lhs.inner() {
|
||||
AssignLhs::Name(name) => {
|
||||
self.scope_mut().insert_local(name);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::syn::Spanned;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Stmt {
|
||||
Assign(AssignLhs, Expr),
|
||||
Assign(SpAssignLhs, SpExpr),
|
||||
Expr(SpExpr),
|
||||
If {
|
||||
if_true: SpCondExpr,
|
||||
@@ -20,6 +20,8 @@ pub enum Stmt {
|
||||
},
|
||||
}
|
||||
|
||||
pub type SpAssignLhs = Spanned<AssignLhs>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum AssignLhs {
|
||||
/// A simple assignment.
|
||||
|
||||
@@ -22,6 +22,13 @@ pub SpStmt = Spanned<Stmt>;
|
||||
|
||||
pub Stmt: Stmt = {
|
||||
<SpExpr> => Stmt::Expr(<>),
|
||||
<lhs:SpAssignLhs> "=" <expr:SpExpr> => Stmt::Assign(lhs, expr),
|
||||
}
|
||||
|
||||
pub SpAssignLhs = Spanned<AssignLhs>;
|
||||
|
||||
pub AssignLhs: AssignLhs = {
|
||||
<Name> => { AssignLhs::Name(<>) }
|
||||
}
|
||||
|
||||
pub SpExpr = Spanned<Expr>;
|
||||
|
||||
9097
src/syn/parser.rs
9097
src/syn/parser.rs
File diff suppressed because it is too large
Load Diff
@@ -91,6 +91,18 @@ impl Vm {
|
||||
None
|
||||
}
|
||||
|
||||
pub fn store(&mut self, name: Name, value: Option<ObjPtr>) {
|
||||
for frame in self.frames_mut() {
|
||||
match frame {
|
||||
Frame::User(frame) => {
|
||||
frame.locals_mut().insert(name, value);
|
||||
return;
|
||||
}
|
||||
Frame::Builtin(_frame) => continue,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_frame(&self, fun: ObjPtr, args: Vec<ObjPtr>) -> Option<Frame> {
|
||||
let fun_any = fun.as_any();
|
||||
if fun_any.is::<BuiltinFun>() {
|
||||
@@ -134,7 +146,11 @@ impl Vm {
|
||||
todo!("Throw exception: Could not load name {name:?} (is it set?)");
|
||||
}
|
||||
}
|
||||
Inst::Store(_name) => todo!(),
|
||||
Inst::Store(name) => {
|
||||
let name = *name;
|
||||
let value = self.pop_stack().expect("Stack underflow");
|
||||
self.store(name, Some(value));
|
||||
}
|
||||
Inst::GetAttr(_attr) => todo!(),
|
||||
Inst::Pop => {
|
||||
self
|
||||
|
||||
Reference in New Issue
Block a user