(* BSD 2-Clause License Copyright (c) 2018-2019, Anton Krotov All rights reserved. *) MODULE Compiler; IMPORT ST := STATEMENTS, PARS, UTILS, PATHS, PROG, C := CONSOLE, ERRORS, STRINGS, mConst := CONSTANTS, WRITER, MSP430; 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_sELFSO32 THEN res := mConst.Target_iELFSO32 ELSIF s = mConst.Target_sELF64 THEN res := mConst.Target_iELF64 ELSIF s = mConst.Target_sELFSO64 THEN res := mConst.Target_iELFSO64 ELSIF s = mConst.Target_sMSP430 THEN res := mConst.Target_iMSP430 ELSE res := 0 END RETURN res END Target; PROCEDURE keys (VAR options: PROG.OPTIONS; VAR out: PARS.PATH); VAR param: PARS.PATH; i, j: INTEGER; end: BOOLEAN; value: INTEGER; minor, major: INTEGER; checking: SET; BEGIN out := ""; checking := options.checking; end := FALSE; i := 3; 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 options.stack := value END; IF param[0] = "-" THEN DEC(i) END ELSIF param = "-out" THEN INC(i); UTILS.GetArg(i, param); IF param[0] = "-" THEN DEC(i) ELSE out := param END ELSIF param = "-ram" THEN INC(i); UTILS.GetArg(i, param); IF STRINGS.StrToInt(param, value) THEN options.ram := value END; IF param[0] = "-" THEN DEC(i) END ELSIF param = "-rom" THEN INC(i); UTILS.GetArg(i, param); IF STRINGS.StrToInt(param, value) THEN options.rom := value 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 options.version := major * 65536 + minor END; IF param[0] = "-" THEN DEC(i) END ELSIF param = "-pic" THEN options.pic := TRUE ELSIF param = "" THEN end := TRUE ELSE ERRORS.BadParam(param) END; INC(i) UNTIL end; options.checking := checking 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; bit_depth: INTEGER; time: INTEGER; options: PROG.OPTIONS; BEGIN options.stack := 2; options.version := 65536; options.pic := FALSE; options.checking := ST.chkALL; PATHS.GetCurrentDirectory(app_path); lib_path := app_path; UTILS.GetArg(1, inname); C.Ln; C.String("Akron Oberon Compiler v"); C.Int(mConst.vMajor); C.String("."); C.Int2(mConst.vMinor); C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit)"); C.StringLn("Copyright (c) 2018-2019, Anton Krotov"); IF inname = "" THEN 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 | elfso | elfexe64 | elfso64 | msp430'); C.Ln; ELSIF UTILS.bit_depth = 32 THEN C.StringLn('target = console | gui | dll | kos | obj | elfexe | elfso | msp430'); C.Ln; END; C.StringLn("optional settings:"); C.Ln; C.StringLn(" -out output"); C.Ln; C.StringLn(" -stk set size of stack in megabytes"); C.Ln; C.StringLn(' -nochk <"ptibcwra"> disable runtime checking (pointers, types, indexes,'); C.StringLn(' BYTE, CHR, WCHR)'); C.Ln; C.StringLn(" -ver set version of program ('obj' target)"); C.Ln; C.StringLn(" -ram set size of RAM in bytes ('msp430' target)"); C.Ln; C.StringLn(" -rom set size of ROM in bytes ('msp430' target)"); C.Ln; UTILS.Exit(0) END; PATHS.split(inname, path, modname, ext); IF ext # mConst.FILE_EXT THEN ERRORS.Error(207) END; IF PATHS.isRelative(path) THEN PATHS.RelPath(app_path, path, temp); path := temp END; UTILS.GetArg(2, param); IF param = "" THEN ERRORS.Error(205) END; target := Target(param); IF target = 0 THEN ERRORS.Error(206) END; CASE target OF |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64, mConst.Target_iELF64, mConst.Target_iELFSO64: bit_depth := 64 |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL, mConst.Target_iKolibri, mConst.Target_iObject, mConst.Target_iELF32, mConst.Target_iELFSO32: bit_depth := 32 |mConst.Target_iMSP430: bit_depth := 16; options.ram := MSP430.minRAM; options.rom := MSP430.minROM END; IF UTILS.bit_depth < bit_depth THEN ERRORS.Error(206) END; STRINGS.append(lib_path, "lib"); STRINGS.append(lib_path, UTILS.slash); CASE target OF |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL: STRINGS.append(lib_path, "Windows32") |mConst.Target_iKolibri, mConst.Target_iObject: STRINGS.append(lib_path, "KolibriOS") |mConst.Target_iELF32, mConst.Target_iELFSO32: STRINGS.append(lib_path, "Linux32") |mConst.Target_iELF64, mConst.Target_iELFSO64: STRINGS.append(lib_path, "Linux64") |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64: STRINGS.append(lib_path, "Windows64") |mConst.Target_iMSP430: STRINGS.append(lib_path, "MSP430") END; STRINGS.append(lib_path, UTILS.slash); keys(options, outname); IF outname = "" THEN outname := path; STRINGS.append(outname, modname); CASE target OF |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iConsole64, mConst.Target_iGUI64: STRINGS.append(outname, ".exe") |mConst.Target_iObject: STRINGS.append(outname, ".obj") |mConst.Target_iKolibri, mConst.Target_iELF32, mConst.Target_iELF64: |mConst.Target_iELFSO32, mConst.Target_iELFSO64: STRINGS.append(outname, ".so") |mConst.Target_iDLL, mConst.Target_iDLL64: STRINGS.append(outname, ".dll") |mConst.Target_iMSP430: STRINGS.append(outname, ".hex") END ELSE IF PATHS.isRelative(outname) THEN PATHS.RelPath(app_path, outname, temp); outname := temp END END; PARS.init(bit_depth, target, options); PARS.program.dll := target IN {mConst.Target_iELFSO32, mConst.Target_iELFSO64, mConst.Target_iDLL, mConst.Target_iDLL64, mConst.Target_iObject}; PARS.program.obj := target = mConst.Target_iObject; ST.compile(path, lib_path, modname, outname, target, options); time := UTILS.GetTickCount() - UTILS.time; C.Int(PARS.lines); C.String(" lines, "); 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.