-
Notifications
You must be signed in to change notification settings - Fork 18
Register Machine Code Format
<Here goes a description of the register machine code format, similar to Section 5.1.5 of SICP JS>
Based on SICP Instruction Summary 5.1.5:
This section is still work in progress.
Assigning a value from register 'register-name-from' to 'register-name-to':
assign(register-name-to, reg(register-name-from))
For example, if you assign contents from register D to register C:
assign("C", reg("D"))
Assigns a constant value to 'register-name'. Constant value is predefined.
assign(register-name, constant(constant-value))
- "register-name" seen in round brackets are just the actual register names in strings.
Even though SICP Instruction Summary 5.1.5 is already listed some instructions, we will remention it here as some instrcution APIs are not consistent.
Perform an operation:
perform(list(op(operation_name), inputs...))
Test an operation:
test(list(op(operation_name), inputs...))
make a branch with a label:
branch(label(label_name))
Go to corresponding label_name value:
go_to(label(label_name))
Go to corredponding register value:
go_to(reg(register_name))
Save the register value into stack:
save(register_name)
Restore the value from stack to register:
restore(register_name)
Get the Nth element of the vector:
vector_ref(vector,n)
Set the Nth element of the vector with a value:
vector_set(vector, n, value)
Having seen what are some examples of register machine instructions, we can now explore the different register machine instructions that result from compiling Source programs.
We shall discuss the following compilation results:
- self-evaluating expressions
- constant declarations
- variable declarations
- variable assignments
- function definitions
- and more ...
The machine instruction that results in compilation of self-evaluating expression is as follows. The general form is:
assign(val, constant(self-evaluating expr))
Thus, a Source expression such as
true;
4215;
can produce the following machine instructions:
assign(val, constant(true)),
assign(val, constant(4215))
Usually constants are defined using a const keyword. The following shows the general form for constant declarations:
const course_number = 4215;
const enrolment_status = true;
The above expressions can produce the following machine instructions:
assign(val, constant(4215)),
perform(op(define_constant), constant(course_number), reg(val), reg(env)),
assign(val, constant(1)),
assign(val, constant(true)),
perform(op(define_constant), constant(enrolment_status), reg(val), reg(env)),
assign(val, constant(1))
Should you prefer to declare variables using let instead, the following applies: An expression such as
let x = 1010;
can result in compiled machine instructions:
assign(val, constant(1010)),
perform(op(define_variable), constant(x), reg(val), reg(env)),
assign(val, constant(1))
Now, let's say that we are interested in modifying a previously declared variable, we can do this.
let subject_code = 3243; // Just a reminder that we have to use the 'let' keyword instead of 'const' here.
subject_code = 4215;
The above Source program can result in such a machine instruction:
assign(val, constant(3243)),
perform(op(define_variable), constant(subject_code), reg(val), reg(env)),
assign(val, constant(1)),
assign(val, constant(4215)),
perform(op(define_variable), constant(subject_code), reg(val), reg(env)),
assign(val, constant(1))
Furthermore, we can also compile function expressions and obtain its corresponding machine instructions. The Source program
(x,y) => {x; 1234; return 5678;}
can produce such a register machine instruction after compilation.
assign(val, op(make_compiled_procedure), label(entry1), reg(env)),
go_to(label(after_lambda2)),
entry1,
assign(env, op(compiled_procedure_env), reg(proc)),
assign(env, op(extend_environment), constant([["name", ["x", null]], [["name", ["y", null]], null]]), reg(arg1), reg(env)),
assign(val, op(lookup_variable_value), reg(env), constant(x)),
assign(val, constant(1234)),
assign(val, constant(5678)),
go_to(reg(continue)),
after_lambda2
Whew, there we have it.