// main-s.txt
//   public release som v3.0 	5 March 2007 (Maka-bucha day)
//   public release som v3.1 	19 Aug 2007 (Draft vote day)
//   public release som v4.0    2 July 2008

//  system area  1 .. MAXSYS-1
//   1..80   tokstring-som
//   101     mode ads
//   110..149 "inputfile"  som-string
//   150..199 "input.lst"  som-string
//   200..249 "input.obj"  som-string

enum
    110 src_file
enum
    150 lst_file
enum
    200 obj_file

to parse | f e tk =
    setcdr im NIL		// clear im
    startlex
    lex
    while tok != tkEOF
        tk = tok
        f = top			// parse, throw away flag
        e = ypop
        if (tk == tkTO) | (tk == tkCOLON)
//			def = append def e
            genex e
        else
            im = append im e

to init_all =
    initSom
    init_list
    def = list newatom OPER tkBB
    im = list newatom OPER tkBB
    initkeysym
    hSym = array hSymsize
    initlex

to loadfile fn =
    if verbose
        prints "load " prints fn nl
    FI = fopen fn 0
    cmode = 0
    parse
    fclose FI
    runimm im

to reloc disp | i k a v d op =
    for i 0 nxsym-1
        k = exsym[i]
        if (getType k) == tyGVAR
            a = getArity k
            v = getRef k	// refresh symtab
            setRef k v+disp
            if or (a == VARRAY) (a == VSTRING)
                d = M[v] + disp
                M[v] = d	// reloc
                setLv k d	// update symtab

    // reloc global in CS
    for i 2 CP-1
        op = CS[i]
        if op > EOC op = 0 // force nop
        a = argAt i
        d = a + disp
        case op_str[op*4]	// op type
            mG: patch i d	// reloc
            mY:
                v = a & 255
                d = (a >> 8) + disp
                patch i (enc2 d v)
            mV: if op == icAds  patch i d
        i = i + 1

to outobj fn | ds =
    ds = array 0			// end of user ds
    reloc 1000-userDS
    FO = fopen fn 1
    fprint FO OBJ_SOM40 fnl
    outhead 2 CP-1
    outM CS 2 CP-1
    outhead 1000 1000+ds-1-userDS
    outM M userDS ds-1		// data
    dumpSym					// symbol table
    fclose FO

to listing fn =
    FO = fopen lst_file 1
    showCode 2 CP-1
    fclose FO

// read-eval-print loop, stdin
to rep =
    while 1
        FI = 0		// stdin
        cmode = 2	// interactive
        printc 62	// >
        parse
        runimm im

to main =
    init_all
    userDS = array 0		// start of user ds
    loadfile "lib2.som"
    if M[mode_ads] == 1		// mode 1 interact, 2 compile&run
        rep
    else
        loadfile src_file
        genfinal
        hashSym
        listing lst_file
        outobj obj_file

// End
