Subversion Repositories Kolibri OS

Rev

Rev 8859 | Rev 9579 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2018-2021, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE Compiler;
  9.  
  10. IMPORT ST := STATEMENTS, PARS, UTILS, PATHS, PROG, C := CONSOLE,
  11.        ERRORS, STRINGS, WRITER, MSP430, THUMB, TARGETS, SCAN, TEXTDRV;
  12.  
  13.  
  14. CONST
  15.  
  16.     DEF_WINDOWS   = "WINDOWS";
  17.     DEF_LINUX     = "LINUX";
  18.     DEF_KOLIBRIOS = "KOLIBRIOS";
  19.     DEF_CPU_X86   = "CPU_X86";
  20.     DEF_CPU_X8664 = "CPU_X8664";
  21.  
  22.  
  23. PROCEDURE keys (VAR options: PROG.OPTIONS; VAR out: PARS.PATH);
  24. VAR
  25.     param: PARS.PATH;
  26.     i, j:  INTEGER;
  27.     _end:  BOOLEAN;
  28.     value: INTEGER;
  29.     minor,
  30.     major: INTEGER;
  31.     checking: SET;
  32.  
  33.  
  34.     PROCEDURE getVal (VAR i: INTEGER; VAR value: INTEGER);
  35.     VAR
  36.         param: PARS.PATH;
  37.         val: INTEGER;
  38.     BEGIN
  39.         INC(i);
  40.         UTILS.GetArg(i, param);
  41.         IF STRINGS.StrToInt(param, val) THEN
  42.             value := val
  43.         END;
  44.         IF param[0] = "-" THEN
  45.             DEC(i)
  46.         END
  47.     END getVal;
  48.  
  49.  
  50. BEGIN
  51.     out := "";
  52.     checking := options.checking;
  53.     _end := FALSE;
  54.     i := 3;
  55.     REPEAT
  56.         UTILS.GetArg(i, param);
  57.  
  58.         IF param = "-stk" THEN
  59.             INC(i);
  60.             UTILS.GetArg(i, param);
  61.             IF STRINGS.StrToInt(param, value) & (1 <= value) & (value <= 32) THEN
  62.                 options.stack := value
  63.             END;
  64.             IF param[0] = "-" THEN
  65.                 DEC(i)
  66.             END
  67.  
  68.         ELSIF param = "-out" THEN
  69.             INC(i);
  70.             UTILS.GetArg(i, param);
  71.             IF param[0] = "-" THEN
  72.                 DEC(i)
  73.             ELSE
  74.                 out := param
  75.             END
  76.  
  77.         ELSIF param = "-tab" THEN
  78.             getVal(i, options.tab)
  79.  
  80.         ELSIF param = "-ram" THEN
  81.             getVal(i, options.ram)
  82.  
  83.         ELSIF param = "-rom" THEN
  84.             getVal(i, options.rom)
  85.  
  86.         ELSIF param = "-nochk" THEN
  87.             INC(i);
  88.             UTILS.GetArg(i, param);
  89.  
  90.             IF param[0] = "-" THEN
  91.                 DEC(i)
  92.             ELSE
  93.                 j := 0;
  94.                 WHILE param[j] # 0X DO
  95.  
  96.                     IF    param[j] = "p" THEN
  97.                         EXCL(checking, ST.chkPTR)
  98.                     ELSIF param[j] = "t" THEN
  99.                         EXCL(checking, ST.chkGUARD)
  100.                     ELSIF param[j] = "i" THEN
  101.                         EXCL(checking, ST.chkIDX)
  102.                     ELSIF param[j] = "b" THEN
  103.                         EXCL(checking, ST.chkBYTE)
  104.                     ELSIF param[j] = "c" THEN
  105.                         EXCL(checking, ST.chkCHR)
  106.                     ELSIF param[j] = "w" THEN
  107.                         EXCL(checking, ST.chkWCHR)
  108.                     ELSIF param[j] = "r" THEN
  109.                         EXCL(checking, ST.chkCHR);
  110.                         EXCL(checking, ST.chkWCHR);
  111.                         EXCL(checking, ST.chkBYTE)
  112.                     ELSIF param[j] = "s" THEN
  113.                         EXCL(checking, ST.chkSTK)
  114.                     ELSIF param[j] = "a" THEN
  115.                         checking := {}
  116.                     END;
  117.  
  118.                     INC(j)
  119.                 END;
  120.  
  121.             END
  122.  
  123.         ELSIF param = "-ver" THEN
  124.             INC(i);
  125.             UTILS.GetArg(i, param);
  126.             IF STRINGS.StrToVer(param, major, minor) THEN
  127.                 options.version := major * 65536 + minor
  128.             END;
  129.             IF param[0] = "-" THEN
  130.                 DEC(i)
  131.             END
  132.  
  133.         ELSIF param = "-lower" THEN
  134.             options.lower := TRUE
  135.  
  136.         ELSIF param = "-pic" THEN
  137.             options.pic := TRUE
  138.  
  139.         ELSIF param = "-def" THEN
  140.             INC(i);
  141.             UTILS.GetArg(i, param);
  142.             SCAN.NewDef(param)
  143.  
  144.         ELSIF param = "" THEN
  145.             _end := TRUE
  146.  
  147.         ELSE
  148.             ERRORS.BadParam(param)
  149.         END;
  150.  
  151.         INC(i)
  152.     UNTIL _end;
  153.  
  154.     options.checking := checking
  155. END keys;
  156.  
  157.  
  158. PROCEDURE OutTargetItem (target: INTEGER; text: ARRAY OF CHAR);
  159. VAR
  160.     width: INTEGER;
  161.  
  162. BEGIN
  163.     width := 15;
  164.     width := width - LENGTH(TARGETS.Targets[target].ComLinePar) - 4;
  165.     C.String("  '"); C.String(TARGETS.Targets[target].ComLinePar); C.String("'");
  166.     WHILE width > 0 DO
  167.         C.String(20X);
  168.         DEC(width)
  169.     END;
  170.     C.StringLn(text)
  171. END OutTargetItem;
  172.  
  173.  
  174. PROCEDURE main;
  175. VAR
  176.     path:       PARS.PATH;
  177.     inname:     PARS.PATH;
  178.     ext:        PARS.PATH;
  179.     app_path:   PARS.PATH;
  180.     lib_path:   PARS.PATH;
  181.     modname:    PARS.PATH;
  182.     outname:    PARS.PATH;
  183.     param:      PARS.PATH;
  184.     temp:       PARS.PATH;
  185.     target:     INTEGER;
  186.     time:       INTEGER;
  187.     options:    PROG.OPTIONS;
  188.  
  189. BEGIN
  190.     options.stack := 2;
  191.     options.tab := TEXTDRV.defTabSize;
  192.     options.version := 65536;
  193.     options.pic := FALSE;
  194.     options.lower := FALSE;
  195.     options.checking := ST.chkALL;
  196.  
  197.     PATHS.GetCurrentDirectory(app_path);
  198.  
  199.     UTILS.GetArg(0, temp);
  200.     PATHS.split(temp, path, modname, ext);
  201.     IF PATHS.isRelative(path) THEN
  202.         PATHS.RelPath(app_path, path, temp);
  203.         path := temp
  204.     END;
  205.     lib_path := path;
  206.  
  207.     UTILS.GetArg(1, inname);
  208.     STRINGS.replace(inname, "\", UTILS.slash);
  209.     STRINGS.replace(inname, "/", UTILS.slash);
  210.  
  211.     C.Ln;
  212.     C.String("Akron Oberon Compiler v"); C.Int(UTILS.vMajor); C.String("."); C.Int2(UTILS.vMinor);
  213.         C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit) " + UTILS.Date);
  214.     C.StringLn("Copyright (c) 2018-2021, Anton Krotov");
  215.  
  216.     IF inname = "" THEN
  217.         C.Ln;
  218.         C.StringLn("Usage: Compiler <main module> <target> [optional settings]"); C.Ln;
  219.         C.StringLn("target =");
  220.         IF UTILS.bit_depth = 64 THEN
  221.             OutTargetItem(TARGETS.Win64C, "Windows64 Console");
  222.             OutTargetItem(TARGETS.Win64GUI, "Windows64 GUI");
  223.             OutTargetItem(TARGETS.Win64DLL, "Windows64 DLL");
  224.             OutTargetItem(TARGETS.Linux64, "Linux64 Exec");
  225.             OutTargetItem(TARGETS.Linux64SO, "Linux64 SO")
  226.         END;
  227.         OutTargetItem(TARGETS.Win32C, "Windows32 Console");
  228.         OutTargetItem(TARGETS.Win32GUI, "Windows32 GUI");
  229.         OutTargetItem(TARGETS.Win32DLL, "Windows32 DLL");
  230.         OutTargetItem(TARGETS.Linux32, "Linux32 Exec");
  231.         OutTargetItem(TARGETS.Linux32SO, "Linux32 SO");
  232.         OutTargetItem(TARGETS.KolibriOS, "KolibriOS Exec");
  233.         OutTargetItem(TARGETS.KolibriOSDLL, "KolibriOS DLL");
  234.         OutTargetItem(TARGETS.MSP430, "MSP430x{1,2}xx microcontrollers");
  235.         OutTargetItem(TARGETS.STM32CM3, "STM32 Cortex-M3 microcontrollers");
  236.         C.Ln;
  237.         C.StringLn("optional settings:"); C.Ln;
  238.         C.StringLn("  -out <file name>      output"); C.Ln;
  239.         C.StringLn("  -stk <size>           set size of stack in Mbytes (Windows, Linux, KolibriOS)"); C.Ln;
  240.         C.StringLn("  -nochk <'ptibcwra'>   disable runtime checking (pointers, types, indexes,");
  241.         C.StringLn("                        BYTE, CHR, WCHR)"); C.Ln;
  242.         C.StringLn("  -lower                allow lower case for keywords"); C.Ln;
  243.         C.StringLn("  -def <identifier>     define conditional compilation symbol"); C.Ln;
  244.         C.StringLn("  -ver <major.minor>    set version of program (KolibriOS DLL)"); C.Ln;
  245.         C.StringLn("  -ram <size>           set size of RAM in bytes (MSP430) or Kbytes (STM32)"); C.Ln;
  246.         C.StringLn("  -rom <size>           set size of ROM in bytes (MSP430) or Kbytes (STM32)"); C.Ln;
  247.         C.StringLn("  -tab <width>          set width for tabs"); C.Ln;
  248.         UTILS.Exit(0)
  249.     END;
  250.  
  251.     C.Dashes;
  252.     PATHS.split(inname, path, modname, ext);
  253.  
  254.     IF ext # UTILS.FILE_EXT THEN
  255.         ERRORS.Error(207)
  256.     END;
  257.  
  258.     IF PATHS.isRelative(path) THEN
  259.         PATHS.RelPath(app_path, path, temp);
  260.         path := temp
  261.     END;
  262.  
  263.     UTILS.GetArg(2, param);
  264.     IF param = "" THEN
  265.         ERRORS.Error(205)
  266.     END;
  267.  
  268.     SCAN.NewDef(param);
  269.  
  270.     IF TARGETS.Select(param) THEN
  271.         target := TARGETS.target
  272.     ELSE
  273.         ERRORS.Error(206)
  274.     END;
  275.  
  276.     IF TARGETS.CPU = TARGETS.cpuMSP430 THEN
  277.         options.ram := MSP430.minRAM;
  278.         options.rom := MSP430.minROM
  279.     END;
  280.  
  281.     IF (TARGETS.CPU = TARGETS.cpuTHUMB) & (TARGETS.OS = TARGETS.osNONE) THEN
  282.         options.ram := THUMB.minRAM;
  283.         options.rom := THUMB.minROM
  284.     END;
  285.  
  286.     IF UTILS.bit_depth < TARGETS.BitDepth THEN
  287.         ERRORS.Error(206)
  288.     END;
  289.  
  290.     STRINGS.append(lib_path, "lib");
  291.     STRINGS.append(lib_path, UTILS.slash);
  292.     STRINGS.append(lib_path, TARGETS.LibDir);
  293.     STRINGS.append(lib_path, UTILS.slash);
  294.  
  295.     keys(options, outname);
  296.     TEXTDRV.setTabSize(options.tab);
  297.     IF outname = "" THEN
  298.         outname := path;
  299.         STRINGS.append(outname, modname);
  300.         STRINGS.append(outname, TARGETS.FileExt)
  301.     ELSE
  302.         IF PATHS.isRelative(outname) THEN
  303.             PATHS.RelPath(app_path, outname, temp);
  304.             outname := temp
  305.         END
  306.     END;
  307.  
  308.     PARS.init(options);
  309.  
  310.     CASE TARGETS.OS OF
  311.     |TARGETS.osNONE:
  312.     |TARGETS.osWIN32,
  313.      TARGETS.osWIN64:   SCAN.NewDef(DEF_WINDOWS)
  314.     |TARGETS.osLINUX32,
  315.      TARGETS.osLINUX64: SCAN.NewDef(DEF_LINUX)
  316.     |TARGETS.osKOS:     SCAN.NewDef(DEF_KOLIBRIOS)
  317.     END;
  318.  
  319.     CASE TARGETS.CPU OF
  320.     |TARGETS.cpuX86:    SCAN.NewDef(DEF_CPU_X86)
  321.     |TARGETS.cpuAMD64:  SCAN.NewDef(DEF_CPU_X8664)
  322.     |TARGETS.cpuMSP430:
  323.     |TARGETS.cpuTHUMB:
  324.     |TARGETS.cpuRVM32I:
  325.     |TARGETS.cpuRVM64I:
  326.     END;
  327.  
  328.     ST.compile(path, lib_path, modname, outname, target, options);
  329.  
  330.     time := UTILS.GetTickCount() - UTILS.time;
  331.     C.Dashes;
  332.     C.Int(PARS.lines); C.String(" lines, ");
  333.     C.Int(time DIV 100); C.String("."); C.Int2(time MOD 100); C.String(" sec, ");
  334.     C.Int(WRITER.counter); C.StringLn(" bytes");
  335.  
  336.     UTILS.Exit(0)
  337. END main;
  338.  
  339.  
  340. BEGIN
  341.     main
  342. END Compiler.