Subversion Repositories Kolibri OS

Rev

Rev 9847 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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