Skip to content

Make names declared as constants immutable #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 21, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 32 additions & 24 deletions evaluator.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/*
Evaluator for a non-deterministic language with booleans, conditionals,
sequences, functions, constants, variables and blocks.

(examples available on our github repo)

/* CONSTANTS: NUMBERS, STRINGS, TRUE, FALSE, NULL */

// constants (numbers, strings, booleans, null)
Expand Down Expand Up @@ -45,9 +43,9 @@ function analyze_amb(exp) {
return is_null(choices)
? fail()
: head(choices)(env,
succeed,
succeed,
() =>
try_next(tail(choices)));
try_next(tail(choices)));
}
return try_next(cfuns);
};
Expand Down Expand Up @@ -128,7 +126,7 @@ function analyze_constant_declaration(stmt) {
return (env, succeed, fail) => {
value_func(env,
(value, fail2) => {
set_name_value(name, value, env);
set_name_value(name, value, env, false);
succeed("constant declared", fail2);
},
fail);
Expand All @@ -155,7 +153,7 @@ function analyze_variable_declaration(stmt) {
return (env, succeed, fail) => {
value_func(env,
(value, fail2) => {
set_name_value(name, value, env);
set_name_value(name, value, env, true);
succeed("variable declared", fail2);
},
fail);
Expand Down Expand Up @@ -412,15 +410,15 @@ function get_args(arg_funcs, env, succeed, fail) {
? succeed(null, fail)
: head(arg_funcs)(env,
// success continuation for this arg_func
(arg, fail2) => {
get_args(tail(arg_funcs),
(arg, fail2) => {
get_args(tail(arg_funcs),
env,
(args, fail3) => {
succeed(pair(arg, args),fail3);
},
fail2);
},
fail);
(args, fail3) => {
succeed(pair(arg, args),fail3);
},
fail2);
},
fail);
}

/* APPLY */
Expand All @@ -429,7 +427,7 @@ function get_args(arg_funcs, env, succeed, fail) {
// primitive functions (which are evaluated using the
// underlying JavaScript), and compound functions.

// Just like deterministic Source,
// Just like deterministic Source,
// application of compound functions is done by evaluating the
// body of the function with respect to an
// environment that results from extending the function
Expand Down Expand Up @@ -499,7 +497,7 @@ function local_names(stmt) {
: insert_all(
local_names(first_statement(stmts)),
local_names(make_sequence(
rest_statements(stmts))));
rest_statements(stmts))));
} else {
return is_constant_declaration(stmt)
? list(constant_declaration_name(stmt))
Expand Down Expand Up @@ -626,12 +624,22 @@ function is_empty_environment(env) {
// the initial value to the name in the first
// (innermost) frame of the given environment

function set_name_value(name, val, env) {
function set_name_value(name, val, env, is_variable) {
// set_value is used for setting a given value
// at the head of given list, as well as to
// store a boolean indicating whether the name of
// the given value was declared as a variable or not

function set_value(vals, val, is_variable) {
set_head(head(vals), val);
set_tail(head(vals), is_variable);
}

function scan(names, vals) {
return is_null(names)
? error("internal error: name not found")
: name === head(names)
? set_head(head(vals), val)
? set_value(vals, val, is_variable)
: scan(tail(names), tail(vals));
}
const frame = first_frame(env);
Expand Down Expand Up @@ -659,11 +667,11 @@ function lookup_name_value(name, env) {
const frame = first_frame(env);
const value = scan(frame_names(frame),
frame_values(frame));
if (value === no_value_yet) {
if (value === no_value_yet) {
error(name, "Name used before declaration: ");
} else {
return value;
}
return value;
}
}
}
return env_loop(env);
Expand All @@ -681,8 +689,8 @@ function assign_name_value(name, val, env) {
? env_loop(
enclosing_environment(env))
: name === head(names)
? ( tail(head(vals))
? set_head(head(vals), val)
? (tail(head(vals))
? set_head(head(vals), val) // the name was declared as a variable
: error("no assignment " +
"to constants allowed") )
: scan(tail(names), tail(vals));
Expand Down Expand Up @@ -885,7 +893,7 @@ function driver_loop() {
display(output_prompt + user_print(val));
return internal_loop(next_alternative);
},
// ambeval failure
// ambeval failure
() => {
display("There are no more values of " +
user_print(input));
Expand Down