global var CH CP CS isNum c (c >= 48) & (c <= 57) isSpace c (c == 32) | (c == 10) | (c < 0) readc { c } c = getchar() // printc c CH = c ret c readi c { n pos } n = c - 48 pos = n while ! isSpace readc n = n*10 + CH - 48 if pos != 0 ret n else ret 0-n // it reads input and write it to screen boot {op arg i} op = readi readc while op != 0 arg = readi readc // CS[i] = (arg << 8) | op print op printc 32 print arg printc 10 // i++ op = readi readc // this is the first image // it can read s-object stream // we test it by appending some s-object // at the end of the first image // and "boot" will read it then write it // out to the screen. // for example: 32 17 23 0 38 1 0 // for the s-code and executable files // of this first image // see "boot1-s.txt" "boot1.obj" // after the basic functions are working // now we write boot2 to be used to load // subsequent functions // i is set to the appropriate address // (after boot2) boot2 {op arg i} CS = 0 i = 130 op = readi readc while op != 0 arg = readi readc CS[i] = (arg << 8) | op i++ op = readi readc // the second stage is to write // a scanner that can read symbols // and store them in a symbol table // the scanner is called "lexical analyser" // this is the symbol table // ??? explain trie symbol table freecell = 0 // pointer to free sym sym = 2000 // symbol table, array 1000 tkval = 0 // value of current token // a cell has 4 fields: char,right,next,atr newcell c { k } k = freecell freecell = freecell + 4 sym[k] = c ret k search i c // if sym[i]=0 insert c at i if sym[i] == 0 sym[i] = newcell c ret sym[i] // return index to symtab, 0 if EOF, 1 if num lex { i } while isSpace readc if CH < 0 break // skip blank stop at EOF if isNum CH tkval = readi CH ret 1 // it is a number i = 0 while ! isSpace CH // check sep, EOF i = search i+2 CH // next of i while sym[i] != CH // match right i = search i+1 CH // right of i CH = readc // read next ret i // we test lex by appending some symbols // at the end and read them until found 0 testlex { i } sym = array 100 i = lex while tkval != 0 print i printc 32 i = lex // now we use "boot2" to read these codes // into code segment and call testlex // example of input to testlex 1 2 aa bb x 0 // now is the final stage // // lex starts working // we build symbol table by reading // "associative pair" symbol-value // into the table initsym { i j } freecell = 4 sym = array 1000 i = lex // read sym while i > 1 j = lex // read value sym[i+3] = tkval // set value i = lex // read sym // with a symbol table // we can write an assembler outc op arg CS[CP] = (arg << 8) | op CP = CP + 1 asm { i j op } // a tiny assembler i = lex while i > 1 op = sym[i+3] tkval = 0 if op > 23 j = lex outc op tkval i = lex main initsym CS = 301000 CP = 99 asm print fac 6