Subversion Repositories Kolibri OS

Rev

Rev 7209 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2018, 2019, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE Compiler;
  9.  
  10. IMPORT ST := STATEMENTS, PARS, UTILS, PATHS, C := CONSOLE, ERRORS, STRINGS, mConst := CONSTANTS, WRITER;
  11.  
  12.  
  13. PROCEDURE Target (s: ARRAY OF CHAR): INTEGER;
  14. VAR
  15.     res: INTEGER;
  16.  
  17. BEGIN
  18.     IF s = mConst.Target_sConsole THEN
  19.         res := mConst.Target_iConsole
  20.     ELSIF s = mConst.Target_sGUI THEN
  21.         res := mConst.Target_iGUI
  22.     ELSIF s = mConst.Target_sDLL THEN
  23.         res := mConst.Target_iDLL
  24.     ELSIF s = mConst.Target_sKolibri THEN
  25.         res := mConst.Target_iKolibri
  26.     ELSIF s = mConst.Target_sObject THEN
  27.         res := mConst.Target_iObject
  28.     ELSIF s = mConst.Target_sConsole64 THEN
  29.         res := mConst.Target_iConsole64
  30.     ELSIF s = mConst.Target_sGUI64 THEN
  31.         res := mConst.Target_iGUI64
  32.     ELSIF s = mConst.Target_sDLL64 THEN
  33.         res := mConst.Target_iDLL64
  34.     ELSIF s = mConst.Target_sELF32 THEN
  35.         res := mConst.Target_iELF32
  36.     ELSIF s = mConst.Target_sELF64 THEN
  37.         res := mConst.Target_iELF64
  38.     ELSE
  39.         res := 0
  40.     END
  41.  
  42.     RETURN res
  43. END Target;
  44.  
  45.  
  46. PROCEDURE keys (VAR StackSize, BaseAddress, Version: INTEGER; VAR pic: BOOLEAN; VAR checking: SET);
  47. VAR
  48.     param: PARS.PATH;
  49.     i, j:  INTEGER;
  50.     end:   BOOLEAN;
  51.     value: INTEGER;
  52.     minor,
  53.     major: INTEGER;
  54.  
  55. BEGIN
  56.     end := FALSE;
  57.     i := 4;
  58.     REPEAT
  59.         UTILS.GetArg(i, param);
  60.  
  61.         IF param = "-stk" THEN
  62.             INC(i);
  63.             UTILS.GetArg(i, param);
  64.             IF STRINGS.StrToInt(param, value) & (1 <= value) & (value <= 32) THEN
  65.                 StackSize := value
  66.             END;
  67.             IF param[0] = "-" THEN
  68.                 DEC(i)
  69.             END
  70.  
  71.         ELSIF param = "-base" THEN
  72.             INC(i);
  73.             UTILS.GetArg(i, param);
  74.             IF STRINGS.StrToInt(param, value) THEN
  75.                 BaseAddress := ((value DIV 64) * 64) * 1024
  76.             END;
  77.             IF param[0] = "-" THEN
  78.                 DEC(i)
  79.             END
  80.  
  81.         ELSIF param = "-nochk" THEN
  82.             INC(i);
  83.             UTILS.GetArg(i, param);
  84.  
  85.             IF param[0] = "-" THEN
  86.                 DEC(i)
  87.             ELSE
  88.                 j := 0;
  89.                 WHILE param[j] # 0X DO
  90.  
  91.                     IF    param[j] = "p" THEN
  92.                         EXCL(checking, ST.chkPTR)
  93.                     ELSIF param[j] = "t" THEN
  94.                         EXCL(checking, ST.chkGUARD)
  95.                     ELSIF param[j] = "i" THEN
  96.                         EXCL(checking, ST.chkIDX)
  97.                     ELSIF param[j] = "b" THEN
  98.                         EXCL(checking, ST.chkBYTE)
  99.                     ELSIF param[j] = "c" THEN
  100.                         EXCL(checking, ST.chkCHR)
  101.                     ELSIF param[j] = "w" THEN
  102.                         EXCL(checking, ST.chkWCHR)
  103.                     ELSIF param[j] = "r" THEN
  104.                         EXCL(checking, ST.chkCHR);
  105.                         EXCL(checking, ST.chkWCHR);
  106.                         EXCL(checking, ST.chkBYTE)
  107.                     ELSIF param[j] = "a" THEN
  108.                         checking := {}
  109.                     END;
  110.  
  111.                     INC(j)
  112.                 END
  113.             END
  114.  
  115.         ELSIF param = "-ver" THEN
  116.             INC(i);
  117.             UTILS.GetArg(i, param);
  118.             IF STRINGS.StrToVer(param, major, minor) THEN
  119.                 Version := major * 65536 + minor
  120.             END;
  121.             IF param[0] = "-" THEN
  122.                 DEC(i)
  123.             END
  124.  
  125.         ELSIF param = "-pic" THEN
  126.             pic := TRUE
  127.  
  128.         ELSIF param = "" THEN
  129.             end := TRUE
  130.  
  131.         ELSE
  132.             ERRORS.error3("bad parameter: ", param, "")
  133.         END;
  134.  
  135.         INC(i)
  136.     UNTIL end
  137.  
  138. END keys;
  139.  
  140.  
  141. PROCEDURE main;
  142. VAR
  143.     path:       PARS.PATH;
  144.     inname:     PARS.PATH;
  145.     ext:        PARS.PATH;
  146.     app_path:   PARS.PATH;
  147.     lib_path:   PARS.PATH;
  148.     modname:    PARS.PATH;
  149.     outname:    PARS.PATH;
  150.     param:      PARS.PATH;
  151.     temp:       PARS.PATH;
  152.  
  153.     target:     INTEGER;
  154.  
  155.     time:       INTEGER;
  156.  
  157.     StackSize,
  158.     Version,
  159.     BaseAdr:    INTEGER;
  160.     pic:        BOOLEAN;
  161.     checking:   SET;
  162.  
  163.     bits64: BOOLEAN;
  164.  
  165. BEGIN
  166.     StackSize := 2;
  167.     Version := 65536;
  168.     pic := FALSE;
  169.     checking := ST.chkALL;
  170.  
  171.     PATHS.GetCurrentDirectory(app_path);
  172.     lib_path := app_path;
  173.  
  174.     UTILS.GetArg(1, inname);
  175.  
  176.     IF inname = "" THEN
  177.         C.String("Akron Oberon-07/16 Compiler v"); C.Int(mConst.vMajor); C.String("."); C.Int2(mConst.vMinor);
  178.             C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit)"); C.Ln;
  179.         C.StringLn("Usage: Compiler <main module> <output> <target> [optional settings]"); C.Ln;
  180.         IF UTILS.bit_depth = 64 THEN
  181.             C.StringLn('target = console | gui | dll | console64 | gui64 | dll64 | kos | obj | elfexe | elfexe64'); C.Ln;
  182.         ELSIF UTILS.bit_depth = 32 THEN
  183.             C.StringLn('target = console | gui | dll | kos | obj | elfexe'); C.Ln;
  184.         END;
  185.         C.StringLn("optional settings:"); C.Ln;
  186.         C.StringLn("  -stk <size>            set size of stack in megabytes"); C.Ln;
  187.         C.StringLn("  -base <address>        set base address of image in kilobytes"); C.Ln;
  188.         C.StringLn('  -ver <major.minor>     set version of program'); C.Ln;
  189.         C.StringLn('  -nochk <"ptibcwra">    disable runtime checking (pointers, types, indexes,');
  190.         C.StringLn('                         BYTE, CHR, WCHR)'); C.Ln;
  191.         UTILS.Exit(0)
  192.     END;
  193.  
  194.     PATHS.split(inname, path, modname, ext);
  195.  
  196.     IF ext # mConst.FILE_EXT THEN
  197.         ERRORS.error3('inputfile name extension must be "', mConst.FILE_EXT, '"')
  198.     END;
  199.     IF PATHS.isRelative(path) THEN
  200.         PATHS.RelPath(app_path, path, temp);
  201.         path := temp
  202.     END;
  203.  
  204.     UTILS.GetArg(2, outname);
  205.     IF outname = "" THEN
  206.         ERRORS.error1("not enough parameters")
  207.     END;
  208.     IF PATHS.isRelative(outname) THEN
  209.         PATHS.RelPath(app_path, outname, temp);
  210.         outname := temp
  211.     END;
  212.  
  213.     UTILS.GetArg(3, param);
  214.     IF param = "" THEN
  215.         ERRORS.error1("not enough parameters")
  216.     END;
  217.  
  218.     target := Target(param);
  219.  
  220.     IF target = 0 THEN
  221.         ERRORS.error1("bad parameter <target>")
  222.     END;
  223.  
  224.     bits64 := target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64, mConst.Target_iELF64};
  225.  
  226.     IF bits64 THEN
  227.         IF UTILS.bit_depth = 32 THEN
  228.             ERRORS.error1("bad parameter <target>")
  229.         END;
  230.         PARS.init(64, target)
  231.     ELSE
  232.         PARS.init(32, target)
  233.     END;
  234.  
  235.     PARS.program.dll := target IN {mConst.Target_iDLL, mConst.Target_iObject, mConst.Target_iDLL64};
  236.     PARS.program.obj := target = mConst.Target_iObject;
  237.  
  238.     STRINGS.append(lib_path, "lib");
  239.     STRINGS.append(lib_path, UTILS.slash);
  240.  
  241.     IF target IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL} THEN
  242.         IF target = mConst.Target_iDLL THEN
  243.             BaseAdr := 10000000H
  244.         ELSE
  245.             BaseAdr := 400000H
  246.         END;
  247.         STRINGS.append(lib_path, "Windows32")
  248.  
  249.     ELSIF target IN {mConst.Target_iKolibri, mConst.Target_iObject} THEN
  250.         STRINGS.append(lib_path, "KolibriOS")
  251.  
  252.     ELSIF target = mConst.Target_iELF32 THEN
  253.         STRINGS.append(lib_path, "Linux32")
  254.  
  255.     ELSIF target = mConst.Target_iELF64 THEN
  256.         STRINGS.append(lib_path, "Linux64")
  257.  
  258.     ELSIF target IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN
  259.         STRINGS.append(lib_path, "Windows64")
  260.  
  261.     END;
  262.  
  263.     STRINGS.append(lib_path, UTILS.slash);
  264.  
  265.     keys(StackSize, BaseAdr, Version, pic, checking);
  266.  
  267.     ST.compile(path, lib_path, modname, outname, target, Version, StackSize, BaseAdr, pic, checking);
  268.  
  269.     time := UTILS.GetTickCount() - UTILS.time;
  270.  
  271.     C.Int(time DIV 100); C.String("."); C.Int2(time MOD 100); C.String(" sec, ");
  272.     C.Int(WRITER.counter); C.StringLn(" bytes");
  273.  
  274.     UTILS.Exit(0)
  275. END main;
  276.  
  277.  
  278. BEGIN
  279.     main
  280. END Compiler.