From 103b5a283f5f41b65bfa6c47b2f5b22022e56750 Mon Sep 17 00:00:00 2001 From: Tobias Wrigstad Date: Tue, 30 Jun 2020 00:58:26 +0200 Subject: [PATCH 01/21] Started to make a pass over Chapter 5 --- .../processingFunctions/processFigureHtml.js | 16 +- static/assets/stylesheet.css | 25 +- xml/chapter5/chapter5.xml | 2 +- xml/chapter5/section1/section1.xml | 4 +- xml/chapter5/section1/subsection1.xml | 2 +- xml/chapter5/section1/subsection2.xml | 43 +- xml/chapter5/section2/section2.xml | 557 +++++++++++++++++- xml/chapter5/section2/subsection1.xml | 31 +- xml/chapter5/section2/subsection2.xml | 16 +- xml/chapter5/section2/subsection3.xml | 31 +- xml/chapter5/section2/subsection4.xml | 4 +- xml/chapter5/section3/subsection1.xml | 2 +- xml/chapter5/section3/subsection2.xml | 12 +- 13 files changed, 679 insertions(+), 66 deletions(-) diff --git a/javascript/processingFunctions/processFigureHtml.js b/javascript/processingFunctions/processFigureHtml.js index 426fcfd8e..fce2fa8d9 100755 --- a/javascript/processingFunctions/processFigureHtml.js +++ b/javascript/processingFunctions/processFigureHtml.js @@ -11,11 +11,21 @@ export const processFigureHtml = (node, writeTo) => { if (!src && node.getElementsByTagName("FIGURE")[0]) { src = node.getElementsByTagName("FIGURE")[0].getAttribute("src"); } + + let scale_factor = "scale_factor_0"; + if (!node.getAttribute("scale_factor") && node.getElementsByTagName("FIGURE")[0]) { + scale_factor = "scale_factor_" + + node.getElementsByTagName("FIGURE")[0].getAttribute("scale_factor"); + } else { + scale_factor = "scale_factor_" + + node.getAttribute("scale_factor"); + } + const label = node.getElementsByTagName("LABEL")[0]; if (src && !label) { writeTo.push(` - + `); return; } else if (!src) { @@ -24,7 +34,7 @@ export const processFigureHtml = (node, writeTo) => { const images = node.getElementsByTagName("IMAGE"); for (let i = 0; i < images.length; i++) { writeTo.push(` - + `); } } @@ -39,7 +49,7 @@ export const processFigureHtml = (node, writeTo) => { if (src && label) { writeTo.push(`
- `); + `); } const snippet = node.getElementsByTagName("SNIPPET")[0]; diff --git a/static/assets/stylesheet.css b/static/assets/stylesheet.css index 706e90fe5..5c86006bc 100644 --- a/static/assets/stylesheet.css +++ b/static/assets/stylesheet.css @@ -74,6 +74,10 @@ figure > div.snippet { text-align: left; } +figure > pre { + text-align: left; +} + caption { margin: 20px auto !important; text-weight: bold; @@ -84,10 +88,26 @@ h2 { font-size: 18pt !important; } -img { +img.scale_factor_0 { margin: 10px 5px; } +img.scale_factor_1 { + margin: 10px 10%; +} +img.scale_factor_2 { + margin: 10px 15%; +} +img.scale_factor_3 { + margin: 10px 20%; +} +img.scale_factor_4 { + margin: 10px 25%; +} +img.scale_factor_5 { + margin: 10px 30%; +} + reference { display: list-item; } @@ -625,10 +645,10 @@ a.gray { color: #eee; } - a.gray:visited { color: #eee; } + pre.prettyprint{display:block;background-color:#333; cursor: pointer;}pre .nocode{background-color:none;color:#000}pre .str{color:#ffa0a0}pre .kwd{color:#f0e68c;font-weight:bold}pre .com{color:#87ceeb}pre .typ{color:#98fb98}pre .lit{color:#cd5c5c}pre .pun{color:#fff}pre .pln{color:#fff}pre .tag{color:#f0e68c;font-weight:bold}pre .atn{color:#bdb76b;font-weight:bold}pre .atv{color:#ffa0a0}pre .dec{color:#98fb98}ol.linenums{margin-top:0;margin-bottom:0;color:#aeaeae}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}@media print{pre.prettyprint{background-color:none}pre .str,code .str{color:#060}pre .kwd,code .kwd{color:#006;font-weight:bold}pre .com,code .com{color:#600;font-style:italic}pre .typ,code .typ{color:#404;font-weight:bold}pre .lit,code .lit{color:#044}pre .pun,code .pun{color:#440}pre .pln,code .pln{color:#000}pre .tag,code .tag{color:#006;font-weight:bold}pre .atn,code .atn{color:#404}pre .atv,code .atv{color:#060}} pre .str,code .str{color:#fec243}pre .kwd,code .kwd{color:#8470ff}pre .com,code .com{color:#32cd32;font-style:italic}pre .typ,code .typ{color:#6ecbcc}pre .lit,code .lit{color:#d06}pre .pun,code .pun{color:#8b8970}pre .pln,code .pln{color:#0f0f0f}pre .tag,code .tag{color:#9c9cff}pre .htm,code .htm{color:#dda0dd}pre .xsl,code .xsl{color:#d0a0d0}pre .atn,code .atn{color:#46eeee;font-weight:normal}pre .atv,code .atv{color:#eeb4b4}pre .dec,code .dec{color:#3387cc}a{text-decoration:none}pre.prettyprint,code.prettyprint{font-family:'Inconsolata', 'Droid Sans Mono','CPMono_v07 Bold','Droid Sans';font-weight:medium;font-size:9pt;background-color:#0f0f0f;}pre.prettyprint{width:95%;white-space:pre-wrap}pre.prettyprint a,code.prettyprint a{text-decoration:none}ol.linenums{margin-top:0;margin-bottom:0;color:#8b8970}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}@media print{pre.prettyprint,code.prettyprint{background-color:#fff}pre .str,code .str{color:#088}pre .kwd,code .kwd{color:#006;font-weight:bold}pre .com,code .com{color:#oc3;font-style:italic}pre .typ,code .typ{color:#404;font-weight:bold}pre .lit,code .lit{color:#044}pre .pun,code .pun{color:#440}pre .pln,code .pln{color:#000}pre .tag,code .tag{color:#b66ff7;font-weight:bold}pre .htm,code .htm{color:#606;font-weight:bold}pre .xsl,code .xsl{color:#606;font-weight:bold}pre .atn,code .atn{color:#c71585;font-weight:normal}pre .atv,code .atv{color:#088;font-weight:normal}} pre.prettyprint.no-eval {background-color: #fff; cursor: default;} .prettyprint.no-eval span.kwd{color: #f16e6e;}.prettyprint.no-eval span.lit{color: #56bfa2;} @@ -661,6 +681,7 @@ pre.prettyprint{ border: none; } + div.pre-prettyprint > pre.prettyprint.no-eval.prettyprinted { border-left: 1ex solid white; } diff --git a/xml/chapter5/chapter5.xml b/xml/chapter5/chapter5.xml index 5eef23352..a6998675d 100644 --- a/xml/chapter5/chapter5.xml +++ b/xml/chapter5/chapter5.xml @@ -26,7 +26,7 @@ % 2/24/96 use smalltt to make some stuff fit nicely in 5.2 % 2/23/96 use Stabular instead of point-size changes % 2/22/96 new spec for epigraph - %2/19/96 change exp-iter - -> expt-iter + % 2/19/96 change exp-iter - -> expt-iter diff --git a/xml/chapter5/section1/section1.xml b/xml/chapter5/section1/section1.xml index 05304a110..cfc0e340e 100644 --- a/xml/chapter5/section1/section1.xml +++ b/xml/chapter5/section1/section1.xml @@ -104,7 +104,7 @@ function gcd(a, b) { machine that could be constructed from electrical components.
-
+
@@ -136,7 +136,7 @@ function gcd(a, b) {
-
+
diff --git a/xml/chapter5/section1/subsection1.xml b/xml/chapter5/section1/subsection1.xml index 783b84714..e6a1281ba 100644 --- a/xml/chapter5/section1/subsection1.xml +++ b/xml/chapter5/section1/subsection1.xml @@ -124,7 +124,7 @@ controller( "t<-r", // button push "a<-b", // button push "b<-t", // button push - go_to(label("test-b"))), // unconditional branch + go_to(label("test-b"))), // unconditional branch "gcd-done"); // label diff --git a/xml/chapter5/section1/subsection2.xml b/xml/chapter5/section1/subsection2.xml index f03b3fd97..3db89778d 100644 --- a/xml/chapter5/section1/subsection2.xml +++ b/xml/chapter5/section1/subsection2.xml @@ -52,7 +52,7 @@ function remainder(n, d) { The instruction
-
+
@@ -135,18 +135,47 @@ controller( (sqrt-iter (improve guess)))) (sqrt-iter 1.0)) + +function square(x) { + return x * x; +} + +function average(x,y) { + return (x + y) / 2; +} + +function sqrt(x) { + function good_enough(guess) { + return math_abs(square(guess) - x) < 0.001; + } + function improve(guess) { + return average(guess, x / guess); + } + function sqrt_iter(guess) { + return good_enough(guess) + ? guess + : sqrt_iter(improve(guess)); + } + return sqrt_iter(1.0); +} + +display(sqrt(4)); // Should display close to 2 +display(sqrt(9)); // Should display close to 3 +display(sqrt(100)); // Should display close to 10 +// Change 0.001 above to tune precision + function sqrt(x) { - function good_enough(guess, x) { - return abs(square(guess) - x) < 0.001; + function good_enough(guess) { + return math_abs(square(guess) - x) < 0.001; } - function improve(guess, x) { + function improve(guess) { return average(guess, x / guess); } - function sqrt_iter(guess, x) { - return good_enough(guess, x) + function sqrt_iter(guess) { + return good_enough(guess) ? guess - : sqrt_iter(improve(guess, x), x); + : sqrt_iter(improve(guess)); } return sqrt_iter(1.0); } diff --git a/xml/chapter5/section2/section2.xml b/xml/chapter5/section2/section2.xml index 8e07d1fe3..7543d8bb8 100644 --- a/xml/chapter5/section2/section2.xml +++ b/xml/chapter5/section2/section2.xml @@ -97,7 +97,7 @@ gcd-machinegcd_machine() to be a model of the GCD machine of section as follows: - + (define gcd-machine @@ -143,7 +143,7 @@ function gcd_machine() { To compute GCDs with this machine, we set the input registers, start the machine, and examine the result when the simulation terminates: - + (set-register-contents! gcd-machine 'a 206) @@ -156,7 +156,7 @@ set_register_contents(gcd_machine, "a", 206); - + (set-register-contents! gcd-machine 'b 40) @@ -169,20 +169,567 @@ set_register_contents(gcd_machine, "b", 40); - + (start gcd-machine) done + +/// Scroll to bottom of editor to see driver +function assoc(key, records) { + return is_null(records) + ? undefined + : equal(key, head(head(records))) + ? head(records) + : assoc(key, tail(records)); +} + +function is_tagged_list(exp, tag) { + return is_pair(exp) + ? equal(head(exp), tag) + : false; +} + +function get_contents(register) { + return register("get"); +} + +function set_contents(register, value) { + return register("set")(value); +} + +function op(name) { + return list("op", name); +} + +function reg(name) { + return list("reg", name); +} + +function label(name) { + return list("label", name); +} + +function constant(value) { + return list("constant", value); +} + +function branch(label) { + return list("branch", label); +} + +function assign(register_name, source) { + const a = append(list("assign", register_name), source); + return a; +} + +function go_to(label) { + return list("go_to", label); +} + +function test(op, lhs, rhs) { + return list("test", op, lhs, rhs); +} + +function binary_function(f) { // f is binary + return arg_list => + length(arg_list) === 2 + ? apply_in_underlying_javascript( + f, arg_list) + : error(arg_list, + "Incorrect number of arguments passed to binary function "); +} + +function gcd_machine() { + return make_machine(list("a", "b", "t"), + list(list("<", binary_function((a, b) => a < b)), + list("-", binary_function((a, b) => a - b)), + list("=", binary_function((a, b) => a === b))), + list("test-b", + test(op("="), reg("b"), constant(0)), + branch(label("gcd-done")), + go_to(label("rem")), + "rem-done", + assign("t", list(reg("a"))), + assign("a", list(reg("b"))), + assign("b", list(reg("t"))), + go_to(label("test-b")), + "rem", + test(op("<"), reg("a"), reg("b")), + branch(label("rem-done")), + assign("a", list(op("-"), reg("a"), reg("b"))), + go_to(label("rem")), + "gcd-done")); +} + +function make_machine(register_names, ops, controller_text) { + const machine = make_new_machine(); + + map(reg_name => machine("allocate_register")(reg_name), register_names); + machine("install_operations")(ops); + machine("install_instruction_sequence")(assemble(controller_text, machine)); + + return machine; +} + +function make_register(name) { + let contents = "*unassigned*"; + + function dispatch(message) { + if (message === "get") { + return contents; + + } else { + if (message === "set") { + return value => { contents = value; }; + + } else { + error(message, "Unknown request: REGISTER"); + } + } + } + + return dispatch; +} + +function make_stack() { + let stack = null; + + function push(x) { + stack = pair(x, stack); + return "done"; + } + + function pop() { + if (is_null(stack)) { + error("Empty stack: POP"); + + } else { + const top = head(stack); + stack = tail(stack); + return top; + } + } + + function initialize() { + stack = null; + return "done"; + } + + function dispatch(message) { + return message === "push" + ? push + : message === "pop" + ? pop() + : message === "initialize" + ? initialize() + : error("Unknown request: STACK", message); + } + + return dispatch; +} + +function pop(stack) { + return stack("pop"); +} + +function push(stack, value) { + return stack("push")(value); +} + +function make_new_machine() { + const pc = make_register("pc"); + const flag = make_register("flag"); + const stack = make_stack(); + let the_instruction_sequence = null; + let the_ops = list(list("initialize_stack", () => stack("initialize"))); + let register_table = list(list("pc", pc), list("flag", flag)); + + function allocate_register(name) { + if (assoc(name, register_table) === undefined) { + register_table = pair(list(name, make_register(name)), register_table); + + } else { + error(name, "Multiply defined register: "); + } + + return "register_allocated"; + } + + function lookup_register(name) { + const val = assoc(name, register_table); + + return val === undefined + ? error(name, "Unknown register:") + : head(tail(val)); + } + + function execute() { + const insts = get_contents(pc); + + if (is_null(insts)) { + return "done"; + + } else { + const proc = instruction_execution_proc(head(insts)); + proc(); + return execute(); + } + } + + function dispatch(message) { + return message === "start" + ? () => { set_contents(pc, the_instruction_sequence); return execute(); } + : message === "install_instruction_sequence" + ? seq => { the_instruction_sequence = seq; } + : message === "allocate_register" + ? allocate_register + : message === "get_register" + ? lookup_register + : message === "install_operations" + ? ops => { the_ops = append(the_ops, ops); } + : message === "stack" + ? stack + : message === "operations" + ? the_ops + : error(message, "Unknown request: MACHINE"); + } + + return dispatch; +} + +function start(machine) { + return machine("start")(); +} + +function get_register_contents(machine, register_name) { + return get_contents(get_register(machine, register_name)); +} + +function set_register_contents(machine, register_name, value) { + set_contents(get_register(machine, register_name), value); + return "done"; +} + +function get_register(machine, reg_name) { + return machine("get_register")(reg_name); +} + +function assemble(controller_text, machine) { + function receive(insts, labels) { + update_insts(insts, labels, machine); + return insts; + } + + return extract_labels(controller_text, receive); +} + +function extract_labels(text, receive) { + function helper(insts, labels) { + const next_inst = head(text); + + return is_string(next_inst) + ? receive(insts, pair(make_label_entry(next_inst, insts), labels)) + : receive(pair(make_instruction(next_inst), insts), labels); + } + + return text === undefined || is_null(text) + ? receive(null, null) + : extract_labels(tail(text), helper); +} + +function update_insts(insts, labels, machine) { + const pc = get_register(machine, "pc"); + const flag = get_register(machine, "flag"); + const stack = machine("stack"); + const ops = machine("operations"); + + const set_iep = set_instruction_execution_proc; + const make_ef = make_execution_function; + return map(i => set_iep(i, + make_ef(instruction_text(i), + labels, + machine, + pc, + flag, + stack, + ops)), + insts); +} + +function make_instruction(text) { + return pair(text, null); +} + +function instruction_text(inst) { + return head(inst); +} + +function instruction_execution_proc(inst) { + return tail(inst); +} + +function set_instruction_execution_proc(inst, proc) { + set_tail(inst, proc); +} + +function make_label_entry(label_name, insts) { + return pair(label_name, insts); +} + +function lookup_label(labels, label_name) { + const val = assoc(label_name, labels); + + return val === undefined + ? error(label_name, "Undefined label: ASSEMBLE") + : tail(val); +} + +function make_execution_function(inst, labels, machine, pc, flag, stack, ops) { + const x = head(inst); + + return x === "assign" + ? make_assign(inst, machine, labels, ops, pc) + : x === "test" + ? make_test(inst, machine, labels, ops, flag, pc) + : x === "branch" + ? make_branch(inst, machine, labels, flag, pc) + : x === "go_to" + ? make_goto(inst, machine, labels, pc) + : x === "save" + ? make_save(inst, machine, stack, pc) + : x === "restore" + ? make_restore(inst, machine, stack, pc) + : x === "perform" + ? make_perform(inst, machine, labels, ops, pc) + : error(inst, "Unknown instruction type: ASSEMBLE"); +} + +function make_assign(inst, machine, labels, operations, pc) { + const target = get_register(machine, assign_reg_name(inst)); + const value_exp = assign_value_exp(inst); + const value_proc = is_operation_exp(value_exp) + ? make_operation_exp(value_exp, machine, labels, operations) + : make_primitive_exp(head(value_exp), machine, labels); + + function perform_make_assign() { + set_contents(target, value_proc()); + advance_pc(pc); + } + + return perform_make_assign; +} + +function assign_reg_name(assign_instruction) { + return head(tail(assign_instruction)); +} + +function assign_value_exp(assign_instruction) { + return tail(tail(assign_instruction)); +} + +function advance_pc(pc) { + set_contents(pc, tail(get_contents(pc))); +} + +function make_test(inst, machine, labels, operations, flag, pc) { + const condition = test_condition(inst); + + if (is_operation_exp(condition)) { + const condition_fun = make_operation_exp(condition, machine, labels, operations); + + function perform_make_test() { + set_contents(flag, condition_fun()); + advance_pc(pc); + } + + return perform_make_test; + } else { + error(inst, "Bad TEST instruction: ASSEMBLE"); + } +} + +function test_condition(test_instruction) { + return tail(test_instruction); +} + +function make_branch(inst, machine, labels, flag, pc) { + const dest = branch_dest(inst); + + if (is_label_exp(dest)) { + const insts = lookup_label(labels, label_exp_label(dest)); + + function perform_make_branch() { + if (get_contents(flag)) { + set_contents(pc, insts); + + } else { + advance_pc(pc); + } + } + + return perform_make_branch; + + } else { + error(inst, "Bad BRANCH instruction: ASSEMBLE"); + } +} + +function branch_dest(branch_instruction) { + return head(tail(branch_instruction)); +} + +function make_goto(inst, machine, labels, pc) { + const dest = goto_dest(inst); + + if (is_label_exp(dest)) { + const insts = lookup_label(labels, label_exp_label(dest)); + return () => set_contents(pc, insts); + + } else if (is_register_exp(dest)) { + const reg = get_register(machine, register_exp_reg(dest)); + return () => set_contents(pc, get_contents(reg)); + + } else { + error(inst, "Bad GOTO instruction: ASSEMBLE"); + } +} + +function goto_dest(goto_instruction) { + return head(tail(goto_instruction)); +} + +function make_save(inst, machine, stack, pc) { + const reg = get_register(machine, stack_inst_reg_name(inst)); + + function perform_make_save() { + push(stack, get_contents(reg)); + advance_pc(pc); + } + + return perform_make_save; +} + +function make_restore(inst, machine, stack, pc) { + const reg = get_register(machine, stack_inst_reg_name(inst)); + + function perform_make_restore() { + set_contents(reg, pop(stack)); + advance_pc(pc); + } + + return perform_make_restore; +} + +function stack_inst_reg_name(stack_instruction) { + return head(tail(stack_instruction)); +} + +function make_perform(inst, machine, labels, operations, pc) { + const action = perform_action(inst); + + if (is_operation_exp(action)) { + const action_proc = make_operation_exp(action, machine, labels, operations); + return () => { action_proc(); advance_pc(pc); }; + + } else { + error(inst, "Bad PERFORM instruction: ASSEMBLE"); + } +} + +function perform_action(inst) { + return tail(inst); +} + +function make_primitive_exp(exp, machine, labels) { + if (is_constant_exp(exp)) { + const c = constant_exp_value(exp); + return () => c; + + } else if (is_label_exp(exp)) { + const insts = lookup_label(labels, label_exp_label(exp)); + return () => insts; + + } else if (is_register_exp(exp)) { + const r = get_register(machine, register_exp_reg(exp)); + return () => get_contents(r); + + } else { + error(exp, "Unknown expression type: ASSEMBLE"); + } +} + +function is_register_exp(exp) { + return is_tagged_list(exp, "reg"); +} + +function register_exp_reg(exp) { + return head(tail(exp)); +} + +function is_constant_exp(exp) { + return is_tagged_list(exp, "constant"); +} + +function constant_exp_value(exp) { + return head(tail(exp)); +} + +function is_label_exp(exp) { + return is_tagged_list(exp, "label"); +} + +function label_exp_label(exp) { + return head(tail(exp)); +} + +function make_operation_exp(exp, machine, labels, operations) { + const op = lookup_prim(operation_exp_op(exp), operations); + const aprocs = map(e => make_primitive_exp(e, machine, labels), operation_exp_operands(exp)); + + function perform_make_operation_exp() { + return op(map(p => p(), aprocs)); + } + + return perform_make_operation_exp; +} + +function is_operation_exp(exp) { + return is_pair(exp) && is_tagged_list(head(exp), "op"); +} + +function operation_exp_op(operation_exp) { + return head(tail(head(operation_exp))); +} + +function operation_exp_operands(operation_exp) { + return tail(operation_exp); +} + +function lookup_prim(symbol, operations) { + const val = assoc(symbol, operations); + + return val === undefined + ? error(symbol, "Unknown operation: ASSEMBLE") + : head(tail(val)); +} + +const m = gcd_machine(); + +display(set_register_contents(m, "a", 206)); +display(set_register_contents(m, "b", 40)); +display(start(m)); +display(get_register_contents(m, "a")); + start(gcd_machine); "done" - + (get-register-contents gcd-machine 'a) diff --git a/xml/chapter5/section2/subsection1.xml b/xml/chapter5/section2/subsection1.xml index 325f2a2af..f28716f9d 100644 --- a/xml/chapter5/section2/subsection1.xml +++ b/xml/chapter5/section2/subsection1.xml @@ -31,7 +31,7 @@ transform the controller list into instructions for the new machine and installs these as the machines instruction sequence. Make-machineMake_machine returns as its value the modified machine model. - + (define (make-machine register-names ops controller-text) @@ -73,7 +73,7 @@ function make_machine(register_names, ops, controller_text) { make-registermake_register creates a register that holds a value that can be accessed or changed: - + (define (make-register name) @@ -115,7 +115,7 @@ function make_register(name) { proceduresfunctions are used to access registers: - + (define (get-contents register) @@ -153,7 +153,7 @@ function set_contents(register, value) { item onto the stack, to poppop the top item off the stack and return it, and to initializeinitialize the stack to empty. - + (define (make-stack) @@ -223,7 +223,7 @@ function make_stack() { proceduresfunctions are used to access stacks: - + (define (pop stack) @@ -311,7 +311,7 @@ function push(stack, value) { - + (define (make-new-machine) @@ -362,7 +362,7 @@ function push(stack, value) {
- + function make_new_machine() { const pc = make_register("pc"); @@ -371,34 +371,42 @@ function make_new_machine() { let the_instruction_sequence = null; let the_ops = list(list("initialize_stack", () => stack("initialize"))); let register_table = list(list("pc", pc), list("flag", flag)); + function allocate_register(name) { if (assoc(name, register_table) === undefined) { register_table = pair(list(name, make_register(name)), register_table); + } else { error(name, "Multiply defined register: "); } + return "register_allocated"; } + function lookup_register(name) { const val = assoc(name, register_table); + return val === undefined ? error(name, "Unknown register:") : head(tail(val)); } + function execute() { const insts = get_contents(pc); + if (is_null(insts)) { return "done"; + } else { const proc = instruction_execution_proc(head(insts)); proc(); return execute(); } } + function dispatch(message) { return message === "start" - ? () => { set_contents(pc, the_instruction_sequence); - return execute(); } + ? () => { set_contents(pc, the_instruction_sequence); return execute(); } : message === "install_instruction_sequence" ? seq => { the_instruction_sequence = seq; } : message === "allocate_register" @@ -413,6 +421,7 @@ function make_new_machine() { ? the_ops : error(message, "Unknown request: MACHINE"); } + return dispatch; } @@ -456,7 +465,7 @@ function make_new_machine() { to set and examine register contents, as specified at the beginning of section: - + (define (start machine) @@ -496,7 +505,7 @@ function set_register_contents(machine, register_name, value) { in sections and ) use the following to look up the register with a given name in a given machine: - + (define (get-register machine reg-name) diff --git a/xml/chapter5/section2/subsection2.xml b/xml/chapter5/section2/subsection2.xml index 179b5bd79..3a5c834f9 100644 --- a/xml/chapter5/section2/subsection2.xml +++ b/xml/chapter5/section2/subsection2.xml @@ -65,7 +65,7 @@ proceduresfunctions and insert them into the instruction list, and returns the modified list. - + (define (assemble controller-text machine) @@ -98,7 +98,7 @@ function assemble(controller_text, machine) { texttext with the position in the list instsinsts that the label designates. - + (define (extract-labels text receive) @@ -148,7 +148,7 @@ function extract_labels(text, receive) { instsinstswithout explicitly making a compound data structure to hold them. An alternative implementation, which returns an explicit pair of values, is - + (define (extract-labels text) @@ -222,7 +222,7 @@ function assemble_alternative(controller_text, machine) { corresponding execution proceduresfunctions: - + (define (update-insts! insts labels machine) @@ -270,7 +270,7 @@ function update_insts(insts, labels, machine) { procedurefunction is not yet available when extract-labelsextract_labels constructs the instruction, and is inserted later by update-insts!update_insts. - + (define (make-instruction text) @@ -315,7 +315,7 @@ function set_instruction_execution_proc(inst, proc) { Elements of the label table are pairs: - + (define (make-label-entry label-name insts) @@ -328,7 +328,7 @@ function make_label_entry(label_name, insts) { Entries will be looked up in the table with - + (define (lookup-label labels label-name) @@ -352,7 +352,7 @@ function lookup_label(labels, label_name) { The following register-machine code is ambiguous, because the label herehere is defined more than once: - + start (goto (label here)) diff --git a/xml/chapter5/section2/subsection3.xml b/xml/chapter5/section2/subsection3.xml index 392d62aea..1d73c8ff1 100644 --- a/xml/chapter5/section2/subsection3.xml +++ b/xml/chapter5/section2/subsection3.xml @@ -20,7 +20,7 @@ section, this dispatches on the type of instruction to generate the appropriate execution procedurefunction. - + (define (make-execution-procedure inst labels machine @@ -91,7 +91,7 @@ function make_execution_function(inst, labels, machine, pc, flag, stack, ops) { The make-assignmake_assign procedurefunction handles assignassign instructions: - + (define (make-assign inst machine labels operations pc) @@ -129,7 +129,7 @@ function make_assign(inst, machine, labels, operations, pc) { second element of the instruction) and the value expression (the rest of the list that forms the instruction) from the assignassign instruction using the selectors - + (define (assign-reg-name assign-instruction) @@ -189,7 +189,7 @@ function assign_value_exp(assign_instruction) { obtained by executing value-procvalue_fun. Then it advances the pcpc to the next instruction by running the procedurefunction - + (define (advance-pc pc) @@ -198,7 +198,6 @@ function assign_value_exp(assign_instruction) { function advance_pc(pc) { set_contents(pc, tail(get_contents(pc))); - } @@ -220,7 +219,7 @@ function advance_pc(pc) { procedurefunction for the condition is called, the result is assigned to the flagflag register, and the pcpc is advanced: - + (define (make-test inst machine labels operations flag pc) @@ -278,7 +277,7 @@ function test_condition(test_instruction) { also that the label is looked up at assembly time, not each time the branchbranch instruction is simulated. - + (define (make-branch inst machine labels flag pc) @@ -332,7 +331,7 @@ function branch_dest(branch_instruction) { destination may be specified either as a label or as a register, and there is no condition to checkthe pcpc is always set to the new destination. - + (define (make-goto inst machine labels pc) @@ -386,7 +385,7 @@ function goto_dest(goto_instruction) { The stack instructions savesave and restorerestore simply use the stack with the designated register and advance the pcpc: - + @@ -449,7 +448,7 @@ function stack_inst_reg_name(stack_instruction) { time, the action procedurefunction is executed and the pcpc advanced. - + (define (make-perform inst machine labels operations pc) @@ -504,7 +503,7 @@ function perform_action(inst) { proceduresfunctions to produce values for these expressions during the simulation: - + (define (make-primitive-exp exp machine labels) @@ -548,7 +547,7 @@ function make_primitive_exp(exp, machine, labels) { The syntax of regreg, labellabel, and constconstant expressions is determined by - + (define (register-exp? exp) (tagged-list? exp 'reg)) @@ -608,7 +607,7 @@ function label_exp_label(exp) { procedurefunction for an operation expressiona list containing the operation and operand expressions from the instruction: - + (define (make-operation-exp exp machine labels operations) @@ -638,7 +637,7 @@ function make_operation_exp(exp, machine, labels, operations) { The syntax of operation expressions is determined by - + (define (operation-exp? exp) @@ -688,7 +687,7 @@ function operation_exp_operands(operation_exp) { procedurefunction is found by looking up the operation name in the operation table for the machine: - + (define (lookup-prim symbol operations) @@ -736,7 +735,7 @@ function lookup_prim(symbol, operations) { if you tried to restore a register that was not the last one saved, as in the sequence - + (save y) (save x) diff --git a/xml/chapter5/section2/subsection4.xml b/xml/chapter5/section2/subsection4.xml index 7f52c3888..3e51321e5 100644 --- a/xml/chapter5/section2/subsection4.xml +++ b/xml/chapter5/section2/subsection4.xml @@ -18,7 +18,7 @@ interface that prints the statistics, as shown below. We also add an operation to the basic machine model to print the stack statistics, by initializing the-opsthe_ops in make-new-machinemake_new_machine to - + @@ -36,7 +36,7 @@ list(list("initialize-stack", () => stack("initialize")), Here is the new version of make-stackmake_stack: - + (define (make-stack) diff --git a/xml/chapter5/section3/subsection1.xml b/xml/chapter5/section3/subsection1.xml index eea8e08da..613c05336 100644 --- a/xml/chapter5/section3/subsection1.xml +++ b/xml/chapter5/section3/subsection1.xml @@ -153,7 +153,7 @@
-
+
Box-and-pointer and memory-vector representations of the list list(list(1, 2), 3, 4).