(* BSD 2-Clause License Copyright (c) 2018, 2019, Anton Krotov All rights reserved. *) MODULE Compiler; IMPORT ST := STATEMENTS, PARS, UTILS, PATHS, C := CONSOLE, ERRORS, STRINGS, mConst := CONSTANTS, WRITER; PROCEDURE Target (s: ARRAY OF CHAR): INTEGER; VAR res: INTEGER; BEGIN IF s = mConst.Target_sConsole THEN res := mConst.Target_iConsole ELSIF s = mConst.Target_sGUI THEN res := mConst.Target_iGUI ELSIF s = mConst.Target_sDLL THEN res := mConst.Target_iDLL ELSIF s = mConst.Target_sKolibri THEN res := mConst.Target_iKolibri ELSIF s = mConst.Target_sObject THEN res := mConst.Target_iObject ELSIF s = mConst.Target_sConsole64 THEN res := mConst.Target_iConsole64 ELSIF s = mConst.Target_sGUI64 THEN res := mConst.Target_iGUI64 ELSIF s = mConst.Target_sDLL64 THEN res := mConst.Target_iDLL64 ELSIF s = mConst.Target_sELF32 THEN res := mConst.Target_iELF32 ELSIF s = mConst.Target_sELF64 THEN res := mConst.Target_iELF64 ELSE res := 0 END RETURN res END Target; PROCEDURE keys (VAR StackSize, BaseAddress, Version: INTEGER; VAR pic: BOOLEAN; VAR checking: SET); VAR param: PARS.PATH; i, j: INTEGER; end: BOOLEAN; value: INTEGER; minor, major: INTEGER; BEGIN end := FALSE; i := 4; REPEAT UTILS.GetArg(i, param); IF param = "-stk" THEN INC(i); UTILS.GetArg(i, param); IF STRINGS.StrToInt(param, value) & (1 <= value) & (value <= 32) THEN StackSize := value END; IF param[0] = "-" THEN DEC(i) END ELSIF param = "-base" THEN INC(i); UTILS.GetArg(i, param); IF STRINGS.StrToInt(param, value) THEN BaseAddress := ((value DIV 64) * 64) * 1024 END; IF param[0] = "-" THEN DEC(i) END ELSIF param = "-nochk" THEN INC(i); UTILS.GetArg(i, param); IF param[0] = "-" THEN DEC(i) ELSE j := 0; WHILE param[j] # 0X DO IF param[j] = "p" THEN EXCL(checking, ST.chkPTR) ELSIF param[j] = "t" THEN EXCL(checking, ST.chkGUARD) ELSIF param[j] = "i" THEN EXCL(checking, ST.chkIDX) ELSIF param[j] = "b" THEN EXCL(checking, ST.chkBYTE) ELSIF param[j] = "c" THEN EXCL(checking, ST.chkCHR) ELSIF param[j] = "w" THEN EXCL(checking, ST.chkWCHR) ELSIF param[j] = "r" THEN EXCL(checking, ST.chkCHR); EXCL(checking, ST.chkWCHR); EXCL(checking, ST.chkBYTE) ELSIF param[j] = "a" THEN checking := {} END; INC(j) END END ELSIF param = "-ver" THEN INC(i); UTILS.GetArg(i, param); IF STRINGS.StrToVer(param, major, minor) THEN Version := major * 65536 + minor END; IF param[0] = "-" THEN DEC(i) END ELSIF param = "-pic" THEN pic := TRUE ELSIF param = "" THEN end := TRUE ELSE ERRORS.error3("bad parameter: ", param, "") END; INC(i) UNTIL end END keys; PROCEDURE main; VAR path: PARS.PATH; inname: PARS.PATH; ext: PARS.PATH; app_path: PARS.PATH; lib_path: PARS.PATH; modname: PARS.PATH; outname: PARS.PATH; param: PARS.PATH; temp: PARS.PATH; target: INTEGER; time: INTEGER; StackSize, Version, BaseAdr: INTEGER; pic: BOOLEAN; checking: SET; bits64: BOOLEAN; BEGIN StackSize := 2; Version := 65536; pic := FALSE; checking := ST.chkALL; PATHS.GetCurrentDirectory(app_path); lib_path := app_path; UTILS.GetArg(1, inname); IF inname = "" THEN C.String("Akron Oberon-07/16 Compiler v"); C.Int(mConst.vMajor); C.String("."); C.Int2(mConst.vMinor); C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit)"); C.Ln; C.StringLn("Usage: Compiler
[optional settings]"); C.Ln; IF UTILS.bit_depth = 64 THEN C.StringLn('target = console | gui | dll | console64 | gui64 | dll64 | kos | obj | elfexe | elfexe64'); C.Ln; ELSIF UTILS.bit_depth = 32 THEN C.StringLn('target = console | gui | dll | kos | obj | elfexe'); C.Ln; END; C.StringLn("optional settings:"); C.Ln; C.StringLn(" -stk set size of stack in megabytes"); C.Ln; C.StringLn(" -base
set base address of image in kilobytes"); C.Ln; C.StringLn(' -ver set version of program'); C.Ln; C.StringLn(' -nochk <"ptibcwra"> disable runtime checking (pointers, types, indexes,'); C.StringLn(' BYTE, CHR, WCHR)'); C.Ln; UTILS.Exit(0) END; PATHS.split(inname, path, modname, ext); IF ext # mConst.FILE_EXT THEN ERRORS.error3('inputfile name extension must be "', mConst.FILE_EXT, '"') END; IF PATHS.isRelative(path) THEN PATHS.RelPath(app_path, path, temp); path := temp END; UTILS.GetArg(2, outname); IF outname = "" THEN ERRORS.error1("not enough parameters") END; IF PATHS.isRelative(outname) THEN PATHS.RelPath(app_path, outname, temp); outname := temp END; UTILS.GetArg(3, param); IF param = "" THEN ERRORS.error1("not enough parameters") END; target := Target(param); IF target = 0 THEN ERRORS.error1("bad parameter ") END; bits64 := target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64, mConst.Target_iELF64}; IF bits64 THEN IF UTILS.bit_depth = 32 THEN ERRORS.error1("bad parameter ") END; PARS.init(64, target) ELSE PARS.init(32, target) END; PARS.program.dll := target IN {mConst.Target_iDLL, mConst.Target_iObject, mConst.Target_iDLL64}; PARS.program.obj := target = mConst.Target_iObject; STRINGS.append(lib_path, "lib"); STRINGS.append(lib_path, UTILS.slash); IF target IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL} THEN IF target = mConst.Target_iDLL THEN BaseAdr := 10000000H ELSE BaseAdr := 400000H END; STRINGS.append(lib_path, "Windows32") ELSIF target IN {mConst.Target_iKolibri, mConst.Target_iObject} THEN STRINGS.append(lib_path, "KolibriOS") ELSIF target = mConst.Target_iELF32 THEN STRINGS.append(lib_path, "Linux32") ELSIF target = mConst.Target_iELF64 THEN STRINGS.append(lib_path, "Linux64") ELSIF target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN STRINGS.append(lib_path, "Windows64") END; STRINGS.append(lib_path, UTILS.slash); keys(StackSize, BaseAdr, Version, pic, checking); ST.compile(path, lib_path, modname, outname, target, Version, StackSize, BaseAdr, pic, checking); time := UTILS.GetTickCount() - UTILS.time; C.Int(time DIV 100); C.String("."); C.Int2(time MOD 100); C.String(" sec, "); C.Int(WRITER.counter); C.StringLn(" bytes"); UTILS.Exit(0) END main; BEGIN main END Compiler.