forked from KolibriOS/kolibrios
82d72daa76
git-svn-id: svn://kolibrios.org@7597 a494cfbc-eb01-0410-851d-a64ba20cac60
280 lines
8.0 KiB
Plaintext
280 lines
8.0 KiB
Plaintext
(*
|
|
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 <main module> <output> <target> [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 <size> set size of stack in megabytes"); C.Ln;
|
|
C.StringLn(" -base <address> set base address of image in kilobytes"); C.Ln;
|
|
C.StringLn(' -ver <major.minor> 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 <target>")
|
|
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 <target>")
|
|
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. |