home *** CD-ROM | disk | FTP | other *** search
-
- /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
-
- /* Copyright Herve' Touati, Aquarius Project, UC Berkeley */
-
- #include <stream.h>
- #include "hash_table.h"
- #include "string_table.h"
- #include "scan.h"
- #include "tags.h"
- #include "instr.h"
- #include "inst_args.h"
- #include "inst_table.h"
- #include "memory.h"
- #include "assembler.h"
- #include "main.h"
- #include "basics.h"
- #include "top_level.h"
-
- void assembly_print(int first_instruction, int profile_flag)
- {
- for (int i = first_instruction; i < next_instruction; i++) {
- if (profile_flag) printf("%8d# ", P0[i].count);
- printf("%6d: ", i);
- instr_types[P0[i].ID].print(P0[i]);
- }
- }
-
- /* what_to_update == ARG_LABEL or ARG_PROC */
- static void update(int first_instruction, int what_to_update)
- {
- for (int i = first_instruction; i < next_instruction; i++)
- instr_types[P0[i].ID].update(P0[i], what_to_update);
- }
-
- /* in MP0 + 1 = &P0[-5] is the address of the metacall escape */
- /* in NP0 + 1 = &P0[-3] is the address of the unsuccessful termination */
- /* in CP0 + 1 = &P0[-2] is the address of the successful termination */
- /* in FP0 + 1 = &P0[-1] is the address of a fail instruction */
-
- void init_code()
- {
- char *p[3];
-
- p[0] = "call/1";
- p[1] = p[2] = "";
- MP0 = P0 - 1;
- instr_types[ESCAPE].fill(*P0++, p);
- p[0] = "";
- p[1] = p[2] = "";
- instr_types[PROCEED].fill(*P0++, p);
- /* intern the "call/1" string as a procedure name starting at address */
- /* -5 */
- int name = instr_args[ARG_PROC]->fill("call/1");
- instr_args[ARG_PROC]->define(name, -5);
-
- p[0] = "failure/0";
- p[1] = p[2] = "";
- NP0 = P0 - 1;
- instr_types[ESCAPE].fill(*P0++, p);
-
- p[0] = "success/0";
- p[1] = p[2] = "";
- CP0 = P0 - 1;
- instr_types[ESCAPE].fill(*P0++, p);
-
- p[0] = "";
- p[1] = p[2] = "";
- FP0 = P0 - 1;
- instr_types[FAIL].fill(*P0++, p);
- }
-
- void assembly()
- {
- int first_instruction = next_instruction = 0;
- for (;;) {
- SCAN.next_line();
- switch (SCAN.status) {
- case SCAN_EOF:
- update(first_instruction, ARG_LABEL);
- update(0, ARG_PROC);
- return;
- case SCAN_DEF_PROC:
- {
- update(first_instruction, ARG_LABEL);
- first_instruction = next_instruction;
- instr_args[ARG_LABEL]->clear();
- int name = instr_args[ARG_PROC]->fill(SCAN.p[1]);
- instr_args[ARG_PROC]->define(name, next_instruction);
- break;
- }
- case SCAN_DEF_LABEL:
- {
- int label = instr_args[ARG_LABEL]->fill(SCAN.p[0]);
- if (label != LABEL_FAIL)
- instr_args[ARG_LABEL]->define(label, next_instruction);
- break;
- }
- case SCAN_INSTR:
- {
- int ID = instr_ID.get(SCAN.intern_p0);
- if (instr_ID.status == HASH_MISS) {
- cerr << (char*) SCAN.intern_p0 << ": ";
- top_level_error("unknown instr name");
- }
- instr_types[ID].fill(P0[next_instruction++], &(SCAN.p[1]));
- if (next_instruction >= memory_sizes[CODE_SIZE]) {
- cout << "Code size limit exceeded\n";
- exit(1);
- }
- break;
- }
- }
- }
- }
-