Subversion Repositories Kolibri OS

Rev

Rev 7597 | 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, PROG, C := CONSOLE, ERRORS, STRINGS, mConst := CONSTANTS, WRITER, MSP430;
  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_sELFSO32 THEN
  37.         res := mConst.Target_iELFSO32
  38.     ELSIF s = mConst.Target_sELF64 THEN
  39.         res := mConst.Target_iELF64
  40.     ELSIF s = mConst.Target_sELFSO64 THEN
  41.         res := mConst.Target_iELFSO64
  42.     ELSIF s = mConst.Target_sMSP430 THEN
  43.         res := mConst.Target_iMSP430
  44.     ELSE
  45.         res := 0
  46.     END
  47.  
  48.     RETURN res
  49. END Target;
  50.  
  51.  
  52. PROCEDURE keys (VAR options: PROG.OPTIONS);
  53. VAR
  54.     param: PARS.PATH;
  55.     i, j:  INTEGER;
  56.     end:   BOOLEAN;
  57.     value: INTEGER;
  58.     minor,
  59.     major: INTEGER;
  60.     checking: SET;
  61.  
  62. BEGIN
  63.     checking := options.checking;
  64.     end := FALSE;
  65.     i := 4;
  66.     REPEAT
  67.         UTILS.GetArg(i, param);
  68.  
  69.         IF param = "-stk" THEN
  70.             INC(i);
  71.             UTILS.GetArg(i, param);
  72.             IF STRINGS.StrToInt(param, value) & (1 <= value) & (value <= 32) THEN
  73.                 options.stack := value
  74.             END;
  75.             IF param[0] = "-" THEN
  76.                 DEC(i)
  77.             END
  78.  
  79.         ELSIF param = "-base" THEN
  80.             INC(i);
  81.             UTILS.GetArg(i, param);
  82.             IF STRINGS.StrToInt(param, value) THEN
  83.                 options.base := ((value DIV 64) * 64) * 1024
  84.             END;
  85.             IF param[0] = "-" THEN
  86.                 DEC(i)
  87.             END
  88.  
  89.         ELSIF param = "-ram" THEN
  90.             INC(i);
  91.             UTILS.GetArg(i, param);
  92.             IF STRINGS.StrToInt(param, value) THEN
  93.                 options.ram := value
  94.             END;
  95.             IF param[0] = "-" THEN
  96.                 DEC(i)
  97.             END
  98.  
  99.         ELSIF param = "-rom" THEN
  100.             INC(i);
  101.             UTILS.GetArg(i, param);
  102.             IF STRINGS.StrToInt(param, value) THEN
  103.                 options.rom := value
  104.             END;
  105.             IF param[0] = "-" THEN
  106.                 DEC(i)
  107.             END
  108.  
  109.         ELSIF param = "-nochk" THEN
  110.             INC(i);
  111.             UTILS.GetArg(i, param);
  112.  
  113.             IF param[0] = "-" THEN
  114.                 DEC(i)
  115.             ELSE
  116.                 j := 0;
  117.                 WHILE param[j] # 0X DO
  118.  
  119.                     IF    param[j] = "p" THEN
  120.                         EXCL(checking, ST.chkPTR)
  121.                     ELSIF param[j] = "t" THEN
  122.                         EXCL(checking, ST.chkGUARD)
  123.                     ELSIF param[j] = "i" THEN
  124.                         EXCL(checking, ST.chkIDX)
  125.                     ELSIF param[j] = "b" THEN
  126.                         EXCL(checking, ST.chkBYTE)
  127.                     ELSIF param[j] = "c" THEN
  128.                         EXCL(checking, ST.chkCHR)
  129.                     ELSIF param[j] = "w" THEN
  130.                         EXCL(checking, ST.chkWCHR)
  131.                     ELSIF param[j] = "r" THEN
  132.                         EXCL(checking, ST.chkCHR);
  133.                         EXCL(checking, ST.chkWCHR);
  134.                         EXCL(checking, ST.chkBYTE)
  135.                     ELSIF param[j] = "a" THEN
  136.                         checking := {}
  137.                     END;
  138.  
  139.                     INC(j)
  140.                 END;
  141.  
  142.             END
  143.  
  144.         ELSIF param = "-ver" THEN
  145.             INC(i);
  146.             UTILS.GetArg(i, param);
  147.             IF STRINGS.StrToVer(param, major, minor) THEN
  148.                 options.version := major * 65536 + minor
  149.             END;
  150.             IF param[0] = "-" THEN
  151.                 DEC(i)
  152.             END
  153.  
  154.         ELSIF param = "-pic" THEN
  155.             options.pic := TRUE
  156.  
  157.         ELSIF param = "" THEN
  158.             end := TRUE
  159.  
  160.         ELSE
  161.             ERRORS.BadParam(param)
  162.         END;
  163.  
  164.         INC(i)
  165.     UNTIL end;
  166.  
  167.     options.checking := checking
  168. END keys;
  169.  
  170.  
  171. PROCEDURE main;
  172. VAR
  173.     path:       PARS.PATH;
  174.     inname:     PARS.PATH;
  175.     ext:        PARS.PATH;
  176.     app_path:   PARS.PATH;
  177.     lib_path:   PARS.PATH;
  178.     modname:    PARS.PATH;
  179.     outname:    PARS.PATH;
  180.     param:      PARS.PATH;
  181.     temp:       PARS.PATH;
  182.     target:     INTEGER;
  183.     bit_depth:  INTEGER;
  184.     time:       INTEGER;
  185.     options:    PROG.OPTIONS;
  186.  
  187. BEGIN
  188.     options.stack := 2;
  189.     options.version := 65536;
  190.     options.pic := FALSE;
  191.     options.checking := ST.chkALL;
  192.  
  193.     PATHS.GetCurrentDirectory(app_path);
  194.     lib_path := app_path;
  195.  
  196.     UTILS.GetArg(1, inname);
  197.  
  198.     C.Ln;
  199.     C.String("Akron Oberon Compiler v"); C.Int(mConst.vMajor); C.String("."); C.Int2(mConst.vMinor);
  200.         C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit)");
  201.     C.StringLn("Copyright (c) 2018-2019, Anton Krotov");
  202.  
  203.     IF inname = "" THEN
  204.         C.Ln;
  205.         C.StringLn("Usage: Compiler <main module> <output> <target> [optional settings]"); C.Ln;
  206.         IF UTILS.bit_depth = 64 THEN
  207.             C.StringLn('target = console | gui | dll | console64 | gui64 | dll64 | kos | obj | elfexe | elfso | elfexe64 | elfso64 | msp430'); C.Ln;
  208.         ELSIF UTILS.bit_depth = 32 THEN
  209.             C.StringLn('target = console | gui | dll | kos | obj | elfexe | elfso | msp430'); C.Ln;
  210.         END;
  211.         C.StringLn("optional settings:"); C.Ln;
  212.         C.StringLn("  -stk <size>            set size of stack in megabytes"); C.Ln;
  213.         C.StringLn("  -base <address>        set base address of image in kilobytes"); C.Ln;
  214.         C.StringLn('  -ver <major.minor>     set version of program'); C.Ln;
  215.         C.StringLn('  -nochk <"ptibcwra">    disable runtime checking (pointers, types, indexes,');
  216.         C.StringLn('                         BYTE, CHR, WCHR)'); C.Ln;
  217.         C.StringLn("  -ram <size>            set size of RAM in bytes (MSP430)"); C.Ln;
  218.         C.StringLn("  -rom <size>            set size of ROM in bytes (MSP430)"); C.Ln;
  219.         UTILS.Exit(0)
  220.     END;
  221.  
  222.     PATHS.split(inname, path, modname, ext);
  223.  
  224.     IF ext # mConst.FILE_EXT THEN
  225.         ERRORS.Error(207)
  226.     END;
  227.  
  228.     IF PATHS.isRelative(path) THEN
  229.         PATHS.RelPath(app_path, path, temp);
  230.         path := temp
  231.     END;
  232.  
  233.     UTILS.GetArg(2, outname);
  234.     IF outname = "" THEN
  235.         ERRORS.Error(205)
  236.     END;
  237.     IF PATHS.isRelative(outname) THEN
  238.         PATHS.RelPath(app_path, outname, temp);
  239.         outname := temp
  240.     END;
  241.  
  242.     UTILS.GetArg(3, param);
  243.     IF param = "" THEN
  244.         ERRORS.Error(205)
  245.     END;
  246.  
  247.     target := Target(param);
  248.  
  249.     IF target = 0 THEN
  250.         ERRORS.Error(206)
  251.     END;
  252.  
  253.     CASE target OF
  254.     |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64, mConst.Target_iELF64, mConst.Target_iELFSO64:
  255.         bit_depth := 64
  256.     |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL,
  257.      mConst.Target_iKolibri, mConst.Target_iObject, mConst.Target_iELF32, mConst.Target_iELFSO32:
  258.         bit_depth := 32
  259.     |mConst.Target_iMSP430:
  260.         bit_depth := 16;
  261.         options.ram := MSP430.minRAM;
  262.         options.rom := MSP430.minROM
  263.     END;
  264.  
  265.     IF UTILS.bit_depth < bit_depth THEN
  266.         ERRORS.Error(206)
  267.     END;
  268.  
  269.     STRINGS.append(lib_path, "lib");
  270.     STRINGS.append(lib_path, UTILS.slash);
  271.  
  272.     CASE target OF
  273.     |mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL:
  274.         IF target = mConst.Target_iDLL THEN
  275.             options.base := 10000000H
  276.         ELSE
  277.             options.base := 400000H
  278.         END;
  279.         STRINGS.append(lib_path, "Windows32")
  280.  
  281.     |mConst.Target_iKolibri, mConst.Target_iObject:
  282.         STRINGS.append(lib_path, "KolibriOS")
  283.  
  284.     |mConst.Target_iELF32, mConst.Target_iELFSO32:
  285.         STRINGS.append(lib_path, "Linux32")
  286.  
  287.     |mConst.Target_iELF64, mConst.Target_iELFSO64:
  288.         STRINGS.append(lib_path, "Linux64")
  289.  
  290.     |mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64:
  291.         STRINGS.append(lib_path, "Windows64")
  292.  
  293.     |mConst.Target_iMSP430:
  294.         STRINGS.append(lib_path, "MSP430")
  295.  
  296.     END;
  297.  
  298.     STRINGS.append(lib_path, UTILS.slash);
  299.  
  300.     keys(options);
  301.  
  302.     PARS.init(bit_depth, target, options);
  303.  
  304.     PARS.program.dll := target IN {mConst.Target_iELFSO32, mConst.Target_iELFSO64, mConst.Target_iDLL, mConst.Target_iDLL64, mConst.Target_iObject};
  305.     PARS.program.obj := target = mConst.Target_iObject;
  306.  
  307.     ST.compile(path, lib_path, modname, outname, target, options);
  308.  
  309.     time := UTILS.GetTickCount() - UTILS.time;
  310.  
  311.     C.Int(time DIV 100); C.String("."); C.Int2(time MOD 100); C.String(" sec, ");
  312.     C.Int(WRITER.counter); C.StringLn(" bytes");
  313.  
  314.     UTILS.Exit(0)
  315. END main;
  316.  
  317.  
  318. BEGIN
  319.     main
  320. END Compiler.