Subversion Repositories Kolibri OS

Rev

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