Implement set! resolves #3
This commit is contained in:
@@ -63,6 +63,26 @@ pub fn define_variable(var: &Datum, val: Datum, env: &mut Env) -> Datum {
|
|||||||
var.clone()
|
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> {
|
pub fn extend<'a>(vars: Datum, vals: Datum, env: &'a Env) -> Env<'a> {
|
||||||
let mut mappings = vec![];
|
let mut mappings = vec![];
|
||||||
if let (Datum::List(mut vars), Datum::List(mut vals)) = (vars, vals) {
|
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 {
|
fn interpret_define(args: &Vec<Datum>, env: &mut Env) -> Datum {
|
||||||
match &args[1] {
|
match &args[1] {
|
||||||
Symbol(_) => {
|
Symbol(_) => {
|
||||||
@@ -119,7 +130,7 @@ pub fn interpret(exp: &Datum, env: &mut Env) -> Datum {
|
|||||||
Unspecified => Unspecified,
|
Unspecified => Unspecified,
|
||||||
Symbol(_) => environment::lookup_variable_value(exp, env),
|
Symbol(_) => environment::lookup_variable_value(exp, env),
|
||||||
List(v) if has_tag(v, "if") => interpret_if(v, 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, "define") => interpret_define(v, env),
|
||||||
List(v) if has_tag(v, "cond") => panic!("cond-not-supported"),
|
List(v) if has_tag(v, "cond") => panic!("cond-not-supported"),
|
||||||
List(v) if has_tag(v, "let") => panic!("let-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] = &['+', '-', '.', '@', '!'];
|
||||||
|
|||||||
Reference in New Issue
Block a user