Implement set! resolves #3
parent
1da08c0a43
commit
3b3ab96f7d
|
@ -63,6 +63,26 @@ pub fn define_variable(var: &Datum, val: Datum, env: &mut Env) -> Datum {
|
|||
var.clone()
|
||||
}
|
||||
|
||||
pub fn set_variable(var: &Datum, val: Datum, env: &mut Env) -> Datum {
|
||||
if let Datum::Symbol(symbol_name) = var {
|
||||
for mapping in &mut env.mappings {
|
||||
if let (Datum::Symbol(current_name), _) = mapping {
|
||||
if symbol_name == current_name {
|
||||
mapping.1 = val;
|
||||
return var.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
match env.outer {
|
||||
// XXX: search outer environments here
|
||||
// Some(outer_env) => set_variable(var, val, outer_env),
|
||||
_ => panic!("SET-VARIABLE -- unbound-var {:?}", var),
|
||||
}
|
||||
} else {
|
||||
panic!("DEFINE-VARIABLE -- not-a-symbol {:?}", var)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend<'a>(vars: Datum, vals: Datum, env: &'a Env) -> Env<'a> {
|
||||
let mut mappings = vec![];
|
||||
if let (Datum::List(mut vars), Datum::List(mut vals)) = (vars, vals) {
|
||||
|
|
|
@ -42,6 +42,17 @@ fn interpret_if(args: &Vec<Datum>, env: &mut Env) -> Datum {
|
|||
}
|
||||
}
|
||||
|
||||
fn interpret_set(args: &Vec<Datum>, env: &mut Env) -> Datum {
|
||||
match &args[1] {
|
||||
Symbol(_) => {
|
||||
let var = &args[1];
|
||||
let val = interpret(&args[2], env);
|
||||
environment::set_variable(var, val, env)
|
||||
}
|
||||
_ => panic!("INTERPRET-SET -- cannot set {:?}", args),
|
||||
}
|
||||
}
|
||||
|
||||
fn interpret_define(args: &Vec<Datum>, env: &mut Env) -> Datum {
|
||||
match &args[1] {
|
||||
Symbol(_) => {
|
||||
|
@ -119,7 +130,7 @@ pub fn interpret(exp: &Datum, env: &mut Env) -> Datum {
|
|||
Unspecified => Unspecified,
|
||||
Symbol(_) => environment::lookup_variable_value(exp, env),
|
||||
List(v) if has_tag(v, "if") => interpret_if(v, env),
|
||||
List(v) if has_tag(v, "set!") => panic!("assignment-not-supported"),
|
||||
List(v) if has_tag(v, "set!") => interpret_set(v, env),
|
||||
List(v) if has_tag(v, "define") => interpret_define(v, env),
|
||||
List(v) if has_tag(v, "cond") => panic!("cond-not-supported"),
|
||||
List(v) if has_tag(v, "let") => panic!("let-not-supported"),
|
||||
|
|
|
@ -135,4 +135,4 @@ const SPECIAL_INITIAL: &[char] = &[
|
|||
'!', '$', '%', '&', '*', '/', ':', '<', '=', '>', '?', '^', '_', '~', '+', '-',
|
||||
];
|
||||
|
||||
const SPECIAL_SUBSEQUENT: &[char] = &['+', '-', '.', '@'];
|
||||
const SPECIAL_SUBSEQUENT: &[char] = &['+', '-', '.', '@', '!'];
|
||||
|
|
Loading…
Reference in New Issue