diff --git a/Compiler b/Compiler index eb4f560..ae88d7b 100644 Binary files a/Compiler and b/Compiler differ diff --git a/Compiler.exe b/Compiler.exe index e19c927..8e93ae1 100644 Binary files a/Compiler.exe and b/Compiler.exe differ diff --git a/doc/MSP430.txt b/doc/MSP430.txt index a7d88b2..2e41977 100644 --- a/doc/MSP430.txt +++ b/doc/MSP430.txt @@ -75,8 +75,8 @@ UTF-8 с BOM-сигнатурой. SET множество из целых чисел {0 .. 15} 2 BYTE 0 .. 255 1 -2. Максимальная длина идентификаторов - 1024 символов -3. Максимальная длина строковых констант - 1024 символов (UTF-8) +2. Максимальная длина идентификаторов - 255 символов +3. Максимальная длина строковых констант - 511 символов (UTF-8) 4. Максимальная размерность открытых массивов - 5 5. Процедура NEW заполняет нулями выделенный блок памяти 6. Локальные переменные инициализируются нулями diff --git a/doc/STM32.txt b/doc/STM32.txt index 200a5ca..940d1a2 100644 --- a/doc/STM32.txt +++ b/doc/STM32.txt @@ -78,8 +78,8 @@ UTF-8 с BOM-сигнатурой. BYTE 0 .. 255 1 WCHAR символ юникода (0X .. 0FFFFX) 2 -2. Максимальная длина идентификаторов - 1024 символов -3. Максимальная длина строковых констант - 1024 символов (UTF-8) +2. Максимальная длина идентификаторов - 255 символов +3. Максимальная длина строковых констант - 511 символов (UTF-8) 4. Максимальная размерность открытых массивов - 5 5. Процедура NEW заполняет нулями выделенный блок памяти 6. Локальные переменные инициализируются нулями diff --git a/doc/x86.txt b/doc/x86.txt index ce805db..2658ca9 100644 --- a/doc/x86.txt +++ b/doc/x86.txt @@ -94,8 +94,8 @@ UTF-8 с BOM-сигнатурой. BYTE 0 .. 255 1 WCHAR символ юникода (0X .. 0FFFFX) 2 -2. Максимальная длина идентификаторов - 1024 символов -3. Максимальная длина строковых констант - 1024 символов (UTF-8) +2. Максимальная длина идентификаторов - 255 символов +3. Максимальная длина строковых констант - 511 символов (UTF-8) 4. Максимальная размерность открытых массивов - 5 5. Процедура NEW заполняет нулями выделенный блок памяти 6. Глобальные и локальные переменные инициализируются нулями diff --git a/doc/x86_64.txt b/doc/x86_64.txt index 9c242be..5fad7cb 100644 --- a/doc/x86_64.txt +++ b/doc/x86_64.txt @@ -86,8 +86,8 @@ UTF-8 с BOM-сигнатурой. BYTE 0 .. 255 1 WCHAR символ юникода (0X .. 0FFFFX) 2 -2. Максимальная длина идентификаторов - 1024 символов -3. Максимальная длина строковых констант - 1024 символов (UTF-8) +2. Максимальная длина идентификаторов - 255 символов +3. Максимальная длина строковых констант - 511 символов (UTF-8) 4. Максимальная размерность открытых массивов - 5 5. Процедура NEW заполняет нулями выделенный блок памяти 6. Глобальные и локальные переменные инициализируются нулями diff --git a/source/ERRORS.ob07 b/source/ERRORS.ob07 index 872b2ef..c9056bd 100644 --- a/source/ERRORS.ob07 +++ b/source/ERRORS.ob07 @@ -1,7 +1,7 @@ (* BSD 2-Clause License - Copyright (c) 2018-2020, Anton Krotov + Copyright (c) 2018-2021, Anton Krotov All rights reserved. *) @@ -25,6 +25,7 @@ BEGIN CASE warning OF |0: C.StringLn("passing a string value as a fixed array") |1: C.StringLn("endless FOR loop") + |2: C.StringLn("identifier too long") END END WarningMsg; @@ -43,7 +44,7 @@ BEGIN | 3: str := "unclosed string" | 4: str := "illegal character" | 5: str := "string too long" - | 6: str := "identifier too long" + | 7: str := "number too long" | 8..12: str := "number too large" | 13: str := "real numbers not supported" diff --git a/source/IL.ob07 b/source/IL.ob07 index bc17a05..8758638 100644 --- a/source/IL.ob07 +++ b/source/IL.ob07 @@ -166,13 +166,13 @@ TYPE EXPORT_PROC* = POINTER TO RECORD (LISTS.ITEM) label*: INTEGER; - name*: SCAN.LEXSTR + name*: SCAN.IDSTR END; IMPORT_LIB* = POINTER TO RECORD (LISTS.ITEM) - name*: SCAN.LEXSTR; + name*: SCAN.TEXTSTR; procs*: LISTS.LIST END; @@ -181,7 +181,7 @@ TYPE label*: INTEGER; lib*: IMPORT_LIB; - name*: SCAN.LEXSTR; + name*: SCAN.TEXTSTR; count: INTEGER END; @@ -1107,7 +1107,7 @@ BEGIN END fname; -PROCEDURE AddExp* (label: INTEGER; name: SCAN.LEXSTR); +PROCEDURE AddExp* (label: INTEGER; name: SCAN.IDSTR); VAR exp: EXPORT_PROC; @@ -1119,7 +1119,7 @@ BEGIN END AddExp; -PROCEDURE AddImp* (dll, proc: SCAN.LEXSTR): IMPORT_PROC; +PROCEDURE AddImp* (dll, proc: SCAN.TEXTSTR): IMPORT_PROC; VAR lib: IMPORT_LIB; p: IMPORT_PROC; diff --git a/source/PARS.ob07 b/source/PARS.ob07 index 9df80aa..da3fd60 100644 --- a/source/PARS.ob07 +++ b/source/PARS.ob07 @@ -233,7 +233,7 @@ BEGIN _in := TRUE; Next(parser); IF parser.sym = SCAN.lxSTRING THEN - STRINGS.trim(parser.lex.s, fname) + STRINGS.trim(parser.lex.string.s, fname) ELSIF parser.sym = SCAN.lxCHAR THEN fname[0] := CHR(ARITH.Int(parser.lex.value)); fname[1] := 0X @@ -343,7 +343,7 @@ END QIdent; PROCEDURE strcmp* (VAR v: ARITH.VALUE; v2: ARITH.VALUE; operator: INTEGER); VAR - str: SCAN.LEXSTR; + str: SCAN.TEXTSTR; string1, string2: SCAN.STRING; bool: BOOLEAN; @@ -531,25 +531,26 @@ VAR res, sf: INTEGER; BEGIN - IF parser.lex.s = "stdcall" THEN + checklex(parser, SCAN.lxIDENT); + IF parser.lex.ident.s = "stdcall" THEN sf := PROG.sf_stdcall - ELSIF parser.lex.s = "cdecl" THEN + ELSIF parser.lex.ident.s = "cdecl" THEN sf := PROG.sf_cdecl - ELSIF parser.lex.s = "ccall" THEN + ELSIF parser.lex.ident.s = "ccall" THEN sf := PROG.sf_ccall - ELSIF parser.lex.s = "win64" THEN + ELSIF parser.lex.ident.s = "win64" THEN sf := PROG.sf_win64 - ELSIF parser.lex.s = "systemv" THEN + ELSIF parser.lex.ident.s = "systemv" THEN sf := PROG.sf_systemv - ELSIF parser.lex.s = "windows" THEN + ELSIF parser.lex.ident.s = "windows" THEN sf := PROG.sf_windows - ELSIF parser.lex.s = "linux" THEN + ELSIF parser.lex.ident.s = "linux" THEN sf := PROG.sf_linux - ELSIF parser.lex.s = "code" THEN + ELSIF parser.lex.ident.s = "code" THEN sf := PROG.sf_code - ELSIF parser.lex.s = "oberon" THEN + ELSIF parser.lex.ident.s = "oberon" THEN sf := PROG.sf_oberon - ELSIF parser.lex.s = "noalign" THEN + ELSIF parser.lex.ident.s = "noalign" THEN sf := PROG.sf_noalign ELSE check1(FALSE, parser, 124) @@ -611,11 +612,11 @@ END sysflag; PROCEDURE procflag (parser: PARSER; VAR _import: IL.IMPORT_PROC; isProc: BOOLEAN): INTEGER; VAR call: INTEGER; - dll, proc: SCAN.LEXSTR; + dll, proc: SCAN.TEXTSTR; pos: POSITION; - PROCEDURE getStr (parser: PARSER; VAR name: SCAN.LEXSTR); + PROCEDURE getStr (parser: PARSER; VAR name: SCAN.TEXTSTR); VAR pos: POSITION; str: ARITH.VALUE; @@ -996,7 +997,7 @@ VAR proc := IdentDef(parser, PROG.idIMP, name); proc._import := _import; IF _import.name = "" THEN - _import.name := name.s + COPY(name.s, _import.name) END; PROG.program.procs.last(PROG.PROC)._import := _import ELSE @@ -1240,7 +1241,7 @@ BEGIN ExpectSym(parser, SCAN.lxIDENT); IF ~parser.main THEN - check1(parser.lex.s = parser.modname, parser, 23) + check1(parser.lex.ident.s = parser.modname, parser, 23) END; unit := PROG.newUnit(parser.lex.ident); @@ -1300,7 +1301,7 @@ BEGIN checklex(parser, SCAN.lxEND); ExpectSym(parser, SCAN.lxIDENT); - check1(parser.lex.s = unit.name.s, parser, 25); + check1(parser.lex.ident.s = unit.name.s, parser, 25); ExpectSym(parser, SCAN.lxPOINT) END; diff --git a/source/PROG.ob07 b/source/PROG.ob07 index 0ff3e24..9ab73d6 100644 --- a/source/PROG.ob07 +++ b/source/PROG.ob07 @@ -648,10 +648,10 @@ END getUnit; PROCEDURE enterStTypes (unit: UNIT); - PROCEDURE enter (unit: UNIT; nameStr: SCAN.LEXSTR; _type: _TYPE); + PROCEDURE enter (unit: UNIT; nameStr: SCAN.IDSTR; _type: _TYPE); VAR ident: IDENT; - upper: SCAN.LEXSTR; + upper: SCAN.IDSTR; name: SCAN.IDENT; BEGIN @@ -688,10 +688,10 @@ END enterStTypes; PROCEDURE enterStProcs (unit: UNIT); - PROCEDURE Enter (unit: UNIT; nameStr: SCAN.LEXSTR; nfunc, tfunc: INTEGER); + PROCEDURE Enter (unit: UNIT; nameStr: SCAN.IDSTR; nfunc, tfunc: INTEGER); VAR ident: IDENT; - upper: SCAN.LEXSTR; + upper: SCAN.IDSTR; name: SCAN.IDENT; BEGIN @@ -1080,10 +1080,10 @@ VAR name: SCAN.IDENT; - PROCEDURE EnterProc (sys: UNIT; nameStr: SCAN.LEXSTR; idtyp, proc: INTEGER); + PROCEDURE EnterProc (sys: UNIT; nameStr: SCAN.IDSTR; idtyp, proc: INTEGER); VAR ident: IDENT; - upper: SCAN.LEXSTR; + upper: SCAN.IDSTR; name: SCAN.IDENT; BEGIN diff --git a/source/SCAN.ob07 b/source/SCAN.ob07 index 70aecf1..56d5843 100644 --- a/source/SCAN.ob07 +++ b/source/SCAN.ob07 @@ -12,7 +12,9 @@ IMPORT TXT := TEXTDRV, ARITH, S := STRINGS, ERRORS, LISTS; CONST - LEXLEN = 1024; + NUMLEN = 256; + IDLEN = 256; + TEXTLEN = 512; lxUNDEF* = 0; lxIDENT* = 1; lxINTEGER* = 2; lxHEX* = 3; lxCHAR* = 4; lxFLOAT* = 5; lxSTRING* = 6; lxCOMMENT* = 7; @@ -39,31 +41,32 @@ CONST lxWHILE* = 83; lxERROR01* = -1; lxERROR02* = -2; lxERROR03* = -3; lxERROR04* = -4; - lxERROR05* = -5; lxERROR06* = -6; lxERROR07* = -7; lxERROR08* = -8; + lxERROR05* = -5; (*lxERROR06* = -6;*) lxERROR07* = -7; lxERROR08* = -8; lxERROR09* = -9; lxERROR10* = -10; lxERROR11* = -11; lxERROR12* = -12; lxERROR13* = -13; TYPE - LEXSTR* = ARRAY LEXLEN OF CHAR; + TEXTSTR* = ARRAY TEXTLEN OF CHAR; + IDSTR* = ARRAY IDLEN OF CHAR; DEF = POINTER TO RECORD (LISTS.ITEM) - ident: LEXSTR + ident: IDSTR END; STRING* = POINTER TO RECORD (LISTS.ITEM) - s*: LEXSTR; + s*: TEXTSTR; offset*, offsetW*, hash: INTEGER END; IDENT* = RECORD - s*: LEXSTR; + s*: IDSTR; hash*: INTEGER END; @@ -76,17 +79,12 @@ TYPE LEX* = RECORD - s*: LEXSTR; - length*: INTEGER; sym*: INTEGER; - hash: INTEGER; pos*: POSITION; ident*: IDENT; string*: STRING; value*: ARITH.VALUE; - error*: INTEGER; - - over: BOOLEAN + error*: INTEGER END; @@ -136,7 +134,7 @@ BEGIN END checkKW; -PROCEDURE enterStr* (s: LEXSTR): STRING; +PROCEDURE enterStr* (s: TEXTSTR): STRING; VAR str, res: STRING; hash: INTEGER; @@ -158,7 +156,7 @@ BEGIN res.s := s; res.offset := -1; res.offsetW := -1; - res.hash := S.HashStr(s); + res.hash := hash; LISTS.push(strings, res) END @@ -166,18 +164,6 @@ BEGIN END enterStr; -PROCEDURE putchar (VAR lex: LEX; c: CHAR); -BEGIN - IF lex.length < LEXLEN - 1 THEN - lex.s[lex.length] := c; - INC(lex.length); - lex.s[lex.length] := 0X - ELSE - lex.over := TRUE - END -END putchar; - - PROCEDURE nextc (text: TXT.TEXT): CHAR; BEGIN TXT.next(text) @@ -185,69 +171,91 @@ BEGIN END nextc; -PROCEDURE setIdent* (VAR ident: IDENT; s: LEXSTR); +PROCEDURE setIdent* (VAR ident: IDENT; s: IDSTR); BEGIN ident.s := s; - ident.hash := S.HashStr(s); + ident.hash := S.HashStr(s) END setIdent; PROCEDURE ident (text: TXT.TEXT; VAR lex: LEX); VAR c: CHAR; + i: INTEGER; BEGIN c := text.peak; ASSERT(S.letter(c)); - WHILE S.letter(c) OR S.digit(c) DO - putchar(lex, c); + i := 0; + WHILE (i < IDLEN - 1) & (S.letter(c) OR S.digit(c)) DO + lex.ident.s[i] := c; + INC(i); c := nextc(text) END; - IF lex.over THEN - lex.sym := lxERROR06 - ELSE - setIdent(lex.ident, lex.s); - lex.sym := checkKW(lex.ident) - END + lex.ident.s[i] := 0X; + lex.ident.hash := S.HashStr(lex.ident.s); + lex.sym := checkKW(lex.ident); + IF S.letter(c) OR S.digit(c) THEN + ERRORS.WarningMsg(lex.pos.line, lex.pos.col, 2); + WHILE S.letter(c) OR S.digit(c) DO + c := nextc(text) + END + END END ident; PROCEDURE number (text: TXT.TEXT; VAR lex: LEX); +TYPE + NUMSTR = ARRAY NUMLEN OF CHAR; + VAR c: CHAR; hex: BOOLEAN; - error, sym: INTEGER; + error, sym, i: INTEGER; + num: NUMSTR; + + + PROCEDURE push (VAR num: NUMSTR; VAR i: INTEGER; c: CHAR); + BEGIN + IF i < NUMLEN - 1 THEN + num[i] := c; + INC(i) + END + END push; + BEGIN c := text.peak; ASSERT(S.digit(c)); + i := 0; + error := 0; sym := lxINTEGER; hex := FALSE; WHILE S.digit(c) DO - putchar(lex, c); + push(num, i, c); c := nextc(text) END; WHILE S.hexdigit(c) DO - putchar(lex, c); + push(num, i, c); c := nextc(text); hex := TRUE END; IF c = "H" THEN - putchar(lex, c); + push(num, i, c); TXT.next(text); sym := lxHEX ELSIF c = "X" THEN - putchar(lex, c); + push(num, i, c); TXT.next(text); sym := lxCHAR @@ -260,7 +268,7 @@ BEGIN c := nextc(text); IF c # "." THEN - putchar(lex, "."); + push(num, i, "."); sym := lxFLOAT ELSE sym := lxINTEGER; @@ -269,22 +277,22 @@ BEGIN END; WHILE S.digit(c) DO - putchar(lex, c); + push(num, i, c); c := nextc(text) END; IF c = "E" THEN - putchar(lex, c); + push(num, i, c); c := nextc(text); IF (c = "+") OR (c = "-") THEN - putchar(lex, c); + push(num, i, c); c := nextc(text) END; IF S.digit(c) THEN WHILE S.digit(c) DO - putchar(lex, c); + push(num, i, c); c := nextc(text) END ELSE @@ -300,16 +308,19 @@ BEGIN END; - IF lex.over & (sym >= 0) THEN + IF (i = NUMLEN - 1) & (sym >= 0) THEN sym := lxERROR07 END; IF sym = lxINTEGER THEN - ARITH.iconv(lex.s, lex.value, error) + num[i] := 0X; + ARITH.iconv(num, lex.value, error) ELSIF (sym = lxHEX) OR (sym = lxCHAR) THEN - ARITH.hconv(lex.s, lex.value, error) + num[i] := 0X; + ARITH.hconv(num, lex.value, error) ELSIF sym = lxFLOAT THEN - ARITH.fconv(lex.s, lex.value, error) + num[i] := 0X; + ARITH.fconv(num, lex.value, error) END; CASE error OF @@ -328,36 +339,39 @@ END number; PROCEDURE string (text: TXT.TEXT; VAR lex: LEX; quot: CHAR); VAR c: CHAR; - n: INTEGER; + i: INTEGER; + str: TEXTSTR; BEGIN c := nextc(text); - n := 0; - WHILE (c # quot) & (c # 0X) & ~text.eol & ~text.eof DO - putchar(lex, c); + i := 0; + WHILE (i < LEN(str) - 1) & (c # quot) & (c # 0X) & ~text.eol & ~text.eof DO + str[i] := c; c := nextc(text); - INC(n) + INC(i) + END; + + str[i] := 0X; + + IF (i = LEN(str) - 1) & (c # quot) & (c # 0X) & ~text.eol & ~text.eof THEN + lex.sym := lxERROR05 END; IF c = quot THEN TXT.next(text); - IF lex.over THEN - lex.sym := lxERROR05 + IF i # 1 THEN + lex.sym := lxSTRING ELSE - IF n # 1 THEN - lex.sym := lxSTRING - ELSE - lex.sym := lxCHAR; - ARITH.setChar(lex.value, ORD(lex.s[0])) - END + lex.sym := lxCHAR; + ARITH.setChar(lex.value, ORD(str[0])) END - ELSE + ELSIF lex.sym # lxERROR05 THEN lex.sym := lxERROR03 END; IF lex.sym = lxSTRING THEN - lex.string := enterStr(lex.s); + lex.string := enterStr(str); lex.value.typ := ARITH.tSTRING; lex.value.string := lex.string END @@ -402,15 +416,16 @@ BEGIN END comment; -PROCEDURE delimiter (text: TXT.TEXT; VAR lex: LEX; c: CHAR); +PROCEDURE delimiter (text: TXT.TEXT; c: CHAR): INTEGER; VAR sym: INTEGER; + c0: CHAR; BEGIN - putchar(lex, c); + c0 := c; c := nextc(text); - CASE lex.s[0] OF + CASE c0 OF |"+": sym := lxPLUS @@ -441,7 +456,6 @@ BEGIN IF c = "." THEN sym := lxRANGE; - putchar(lex, c); TXT.next(text) END @@ -483,7 +497,6 @@ BEGIN IF c = "=" THEN sym := lxLE; - putchar(lex, c); TXT.next(text) END @@ -492,7 +505,6 @@ BEGIN IF c = "=" THEN sym := lxGE; - putchar(lex, c); TXT.next(text) END @@ -501,7 +513,6 @@ BEGIN IF c = "=" THEN sym := lxASSIGN; - putchar(lex, c); TXT.next(text) END @@ -514,10 +525,9 @@ BEGIN |"}": sym := lxRCURLY - END; - - lex.sym := sym + END + RETURN sym END delimiter; @@ -583,7 +593,7 @@ VAR check(lex.sym = lxIDENT, text, lex, 22); REPEAT - IF IsDef(lex.s) THEN + IF IsDef(lex.ident.s) THEN skip := FALSE END; @@ -635,11 +645,8 @@ BEGIN c := nextc(text) END; - lex.s[0] := 0X; - lex.length := 0; lex.pos.line := text.line; lex.pos.col := text.col; - lex.over := FALSE; IF S.letter(c) THEN ident(text, lex) @@ -648,7 +655,7 @@ BEGIN ELSIF (c = '"') OR (c = "'") THEN string(text, lex, c) ELSIF delimiters[ORD(c)] THEN - delimiter(text, lex, c) + lex.sym := delimiter(text, c) ELSIF c = "$" THEN IF S.letter(nextc(text)) THEN ident(text, lex); @@ -675,12 +682,9 @@ BEGIN ELSIF (c = 7FX) & upto THEN upto := FALSE; lex.sym := lxRANGE; - putchar(lex, "."); - putchar(lex, "."); DEC(lex.pos.col); TXT.next(text) ELSE - putchar(lex, c); TXT.next(text); lex.sym := lxERROR04 END; diff --git a/source/STATEMENTS.ob07 b/source/STATEMENTS.ob07 index 1091903..d54cc6b 100644 --- a/source/STATEMENTS.ob07 +++ b/source/STATEMENTS.ob07 @@ -2064,7 +2064,7 @@ VAR pos: PARS.POSITION; op: INTEGER; e1: PARS.EXPR; - s, s1: SCAN.LEXSTR; + s, s1: SCAN.TEXTSTR; plus, minus: BOOLEAN; @@ -3261,7 +3261,7 @@ VAR rtl: PROG.UNIT; - PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.LEXSTR; idx: INTEGER); + PROCEDURE getproc (rtl: PROG.UNIT; name: SCAN.IDSTR; idx: INTEGER); VAR id: PROG.IDENT; ident: SCAN.IDENT; diff --git a/source/UTILS.ob07 b/source/UTILS.ob07 index 1030048..959d9fb 100644 --- a/source/UTILS.ob07 +++ b/source/UTILS.ob07 @@ -24,7 +24,7 @@ CONST vMajor* = 1; vMinor* = 50; - Date* = "2021-02-04"; + Date* = "2021-02-05"; FILE_EXT* = ".ob07"; RTL_NAME* = "RTL";