The assembler transforms the sequence of controller expressions instructions for a machine into a corresponding list of machine instructions, each with its execution procedure. function. Overall, the assembler is much like the evaluators we studied in chapter 4—there is an input language (in this case, the register-machine language) and we must perform an appropriate action for each type of component in the language.
[1] Using the receive procedure function here is a way to get extract-labels extract_labels to effectively return two values—labels and insts—without explicitly making a compound data structure to hold them. An alternative implementation, which returns an explicit pair of values, is
Original JavaScript
(define (extract-labels text) (if (null? text) (cons '() '()) (let ((result (extract-labels (cdr text)))) (let ((insts (car result)) (labels (cdr result))) (let ((next-inst (car text))) (if (symbol? next-inst) (cons insts (cons (make-label-entry next-inst insts) labels)) (cons (cons (make-instruction next-inst) insts) labels))))))) function extract_labels(controller) { if (is_null(controller)) { return pair(null, null); } else { const result = extract_labels(tail(controller)); const insts = head(result); const labels = tail(result); const next_element = head(controller); return is_string(next_element) ? pair(insts, pair(make_label_entry(next_element, insts), labels)) : pair(pair(make_inst(next_element), insts), labels); } }
which would be called by assemble as follows:
Original JavaScript
(define (assemble controller-text machine) (let ((result (extract-labels controller-text))) (let ((insts (car result)) (labels (cdr result))) (update-insts! insts labels machine) insts))) function assemble(controller, machine) { const result = extract_labels(controller); const insts = head(result); const labels = tail(result); update_insts(insts, labels, machine); return insts; }
You can consider our use of receive as demonstrating an elegant way to return multiple values, or simply an excuse to show off a programming trick. An argument like receive that is the next procedure function to be invoked is called a continuation. Recall that we also used continuations to implement the backtracking control structure in the amb evaluator in section 4.3.3.
5.2.2   The Assembler