home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / prolog / brklyprl.lha / Emulator / assembler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-14  |  2.8 KB  |  116 lines

  1.  
  2. /* Copyright (C) 1988, 1989 Herve' Touati, Aquarius Project, UC Berkeley */
  3.  
  4. /* Copyright Herve' Touati, Aquarius Project, UC Berkeley */
  5.  
  6. #include <stream.h>
  7. #include "hash_table.h"
  8. #include "string_table.h"
  9. #include "scan.h"
  10. #include "tags.h"
  11. #include "instr.h"
  12. #include "inst_args.h"
  13. #include "inst_table.h"
  14. #include "memory.h"
  15. #include "assembler.h"
  16. #include "main.h"
  17. #include "basics.h"
  18. #include "top_level.h"
  19.  
  20. void assembly_print(int first_instruction, int profile_flag) 
  21. {
  22.   for (int i = first_instruction; i < next_instruction; i++) {
  23.     if (profile_flag) printf("%8d# ", P0[i].count);
  24.     printf("%6d: ", i);
  25.     instr_types[P0[i].ID].print(P0[i]);
  26.   }
  27. }
  28.  
  29.  /*  what_to_update == ARG_LABEL or ARG_PROC */
  30. static void update(int first_instruction, int what_to_update)
  31. {
  32.   for (int i = first_instruction; i < next_instruction; i++)
  33.     instr_types[P0[i].ID].update(P0[i], what_to_update);
  34. }
  35.  
  36.  /* in MP0 + 1 = &P0[-5] is the address of the metacall escape */
  37.  /* in NP0 + 1 = &P0[-3] is the address of the unsuccessful termination */
  38.  /* in CP0 + 1 = &P0[-2] is the address of the successful termination */
  39.  /* in FP0 + 1 = &P0[-1] is the address of a fail instruction */
  40.  
  41. void init_code()
  42. {
  43.   char *p[3];
  44.  
  45.   p[0] = "call/1";
  46.   p[1] = p[2] = "";
  47.   MP0 = P0 - 1;
  48.   instr_types[ESCAPE].fill(*P0++, p);
  49.   p[0] = "";
  50.   p[1] = p[2] = "";
  51.   instr_types[PROCEED].fill(*P0++, p);
  52.  /* intern the "call/1" string as a procedure name starting at address */
  53.  /* -5  */
  54.   int name = instr_args[ARG_PROC]->fill("call/1");
  55.   instr_args[ARG_PROC]->define(name, -5);
  56.  
  57.   p[0] = "failure/0";
  58.   p[1] = p[2] = "";
  59.   NP0 = P0 - 1;
  60.   instr_types[ESCAPE].fill(*P0++, p);
  61.  
  62.   p[0] = "success/0";
  63.   p[1] = p[2] = "";
  64.   CP0 = P0 - 1;
  65.   instr_types[ESCAPE].fill(*P0++, p);
  66.  
  67.   p[0] = "";
  68.   p[1] = p[2] = "";
  69.   FP0 = P0 - 1;
  70.   instr_types[FAIL].fill(*P0++, p);
  71. }
  72.  
  73. void assembly() 
  74. {
  75.   int first_instruction = next_instruction = 0;
  76.   for (;;) {
  77.     SCAN.next_line();
  78.     switch (SCAN.status) {
  79.     case SCAN_EOF:
  80.       update(first_instruction, ARG_LABEL);
  81.       update(0, ARG_PROC);
  82.       return;
  83.     case SCAN_DEF_PROC:
  84.       {
  85.     update(first_instruction, ARG_LABEL);
  86.     first_instruction = next_instruction;
  87.     instr_args[ARG_LABEL]->clear();
  88.     int name = instr_args[ARG_PROC]->fill(SCAN.p[1]);
  89.     instr_args[ARG_PROC]->define(name, next_instruction);
  90.     break;
  91.       }
  92.     case SCAN_DEF_LABEL:
  93.       {
  94.     int label = instr_args[ARG_LABEL]->fill(SCAN.p[0]);
  95.     if (label != LABEL_FAIL)
  96.       instr_args[ARG_LABEL]->define(label, next_instruction);
  97.     break;
  98.       }
  99.     case SCAN_INSTR:
  100.       {
  101.     int ID = instr_ID.get(SCAN.intern_p0);
  102.     if (instr_ID.status == HASH_MISS) {
  103.       cerr << (char*) SCAN.intern_p0 << ": ";
  104.       top_level_error("unknown instr name");
  105.     }
  106.     instr_types[ID].fill(P0[next_instruction++], &(SCAN.p[1]));
  107.     if (next_instruction >= memory_sizes[CODE_SIZE]) {
  108.       cout << "Code size limit exceeded\n";
  109.       exit(1);
  110.     }
  111.     break;
  112.       }
  113.     }
  114.   }
  115. }
  116.