// 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
//   public release som v4.1    9 Aug 2008 (Birthday)
//   public release som v4.2    9 Sept 2009 (triple 9, 9/9/2009)

//  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
	clearlis relis

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

//to testlex fn | i =
//	if verbose
//		prints "load " prints fn nl
//	FI = fopen fn 0
//	cmode = 0
//	for i 1 20
//		prtoken lex2 space
//	fclose FI

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, ads stored in relis
	for i 1 (sizeoflis relis)
		k = relis[i]
		op = CS[k]
		if op > EOC op = 0 // force nop
		a = argAt k
		d = a + disp
		case op_str[op*4]	// op type
			mG: patch k d	// reloc
			mY:
				v = a & 255
				d = (a >> 8) + disp
				patch k (enc2 d v)
			mV: patch k d	// lit ads

to outobj fn | ds =
	ds = array 0			// end of user ds
	reloc 1000-userDS
	FO = fopen fn 1
	fprint FO OBJ_SOM41 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

	if M[mode_ads] == 2		// compile & run only
		loadfile src_file
		genfinal
		hashSym
		listing lst_file
		outobj obj_file

// End
