Przeglądaj źródła

Improved scanner:
accept capital letters A-F in hex numbers of the form 0x????????
accept binary numbers of the form 0x??????? also outside the assembler scanner
accept (ignored) quotes in numbers
e.g. possible:
CONST a = 0b'1000'1000'11111;
CONST b = 0x'1234'FFFF'FFFF'0010
CONST c = 1'000'000'000;


git-svn-id: https://svn.inf.ethz.ch/svn/lecturers/a2/trunk@7392 8c9fc860-2736-0410-a75d-ab315db34111

felixf 7 lat temu
rodzic
commit
5014ba8257
1 zmienionych plików z 52 dodań i 69 usunięć
  1. 52 69
      source/FoxScanner.Mod

+ 52 - 69
source/FoxScanner.Mod

@@ -637,27 +637,61 @@ TYPE
 				ELSE Error( Basic.NumberIllegalCharacter );  RETURN 0
 				END
 			END Hexadecimal;
+			
+			PROCEDURE IsHexDigit(ch: CHAR): BOOLEAN;
+			BEGIN
+				RETURN (ch >= "0") & (ch <= "9") OR (ch >= "a") & (ch <="f") OR (ch >= "A") & (ch <= "F") 
+			END IsHexDigit;
+
+			PROCEDURE IsBinaryDigit(ch: CHAR): BOOLEAN;
+			BEGIN
+				RETURN (ch >= "0") & (ch <= "1") 
+			END IsBinaryDigit;
+			
 
 		BEGIN  (* ("0" <= ch) & (ch <= "9") *)
 			result := Number;
 			i := 0;  m := 0;  n := 0;  d := 0;  si := 0;  long := FALSE;
 			
-			IF (ch = "0") & (reader.Peek() = "x") THEN (* hex number *)
-				digits := 0;
-				GetNextCharacter; GetNextCharacter;
-				WHILE (ch >= "0") & (ch <= "9") OR (ch >= "a") & (ch <="f") OR (ch >= "A") & (ch <= "F") DO
-					number := number * 10H + Hexadecimal(ch);
-					INC(digits);
-					GetNextCharacter;
-				END;
-				symbol.hugeint := number;
-				symbol.integer := SHORT(number);
-				IF digits > MaxHexDigits THEN
-					symbol.numberType := Hugeint
-				ELSE
-					symbol.numberType := Integer
+			IF (ch = "0") THEN
+				IF (reader.Peek() = "x") THEN (* hex number *)
+					digits := 0;
+					GetNextCharacter; GetNextCharacter;
+					IF (ch = "'")& IsHexDigit(reader.Peek())  THEN GetNextCharacter END;
+					WHILE IsHexDigit(ch) DO
+						number := number * 10H + Hexadecimal(ch);
+						INC(digits);
+						GetNextCharacter;
+						IF (ch = "'") & IsHexDigit(reader.Peek()) THEN GetNextCharacter END;
+					END;
+					symbol.hugeint := number;
+					symbol.integer := SHORT(number);
+					IF digits > MaxHexDigits THEN
+						symbol.numberType := Hugeint
+					ELSE
+						symbol.numberType := Integer
+					END;
+					RETURN result;
+				ELSIF reader.Peek() = "b" THEN (* binary number *)
+					digits := 0;
+					GetNextCharacter; GetNextCharacter;
+					IF (ch = "'") & IsBinaryDigit(reader.Peek()) THEN GetNextCharacter END;
+					WHILE IsBinaryDigit(ch) DO
+						number := number * 2;
+						INC(digits);
+						IF ch = "1" THEN INC(number) END;
+						GetNextCharacter;
+						IF (ch = "'") & IsBinaryDigit(reader.Peek()) THEN GetNextCharacter END;
+					END;
+					symbol.hugeint := number;
+					symbol.integer := SHORT(number);
+					IF digits > 32 THEN
+						symbol.numberType := Hugeint
+					ELSE
+						symbol.numberType := Integer
+					END;
+					RETURN result;
 				END;
-				RETURN result;
 			END;
 			
 			LOOP  (* read mantissa *)
@@ -673,6 +707,7 @@ TYPE
 					ELSIF d = 0 THEN  (* i > 0 *) d := i
 					ELSE Error( Basic.NumberIllegalCharacter )
 					END
+				ELSIF ch = "'" THEN GetNextCharacter; (* ignore *)
 				ELSE EXIT
 				END
 			END;   (* 0 <= n <= m <= i, 0 <= d <= i *)
@@ -988,9 +1023,10 @@ TYPE
 		Identifier		= '@' | Letter {'@' | '.' | Letter | Digit | '_'} .
 		Letter 				= 'A' | 'B' | .. |  'Z' | 'a' | 'b' |  .. | 'z' .
 		Digit 				= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'.
+		BinaryDigit 	= '0' | '1' .
 		Number			= Integer | Real.
 		Character		= Digit [HexDigit] 'X'.
-		Integer			=  Digit {Digit} | Digit {HexDigit} 'H' | '0x' {HexDigit}.
+		Integer			=  Digit {Digit} | Digit {HexDigit} 'H' | '0x' {HexDigit} | '0b' {BinaryDigit}.
 		Real					= Digit {Digit} '.' {Digit} [ScaleFactor].
 		ScaleFactor	= ('E' | 'D') ['+' | '-'] digit {digit}.
 		HexDigit		= Digit | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'.
@@ -1058,59 +1094,6 @@ TYPE
 			symbol.identifierString[i] := 0X;
 		END GetIdentifier;
 
-		PROCEDURE GetNumber(VAR symbol: Symbol): Token;
-		VAR number: HUGEINT; result: Token; digits: LONGINT;
-
-			(** return hexadecimal number associated to character ch, error if none **)
-			PROCEDURE Hexadecimal( ch: CHAR ): LONGINT;
-			BEGIN
-				IF (ch >= "0") & (ch <= "9") THEN RETURN ORD( ch ) - ORD( "0" )
-				ELSIF (ch >= "a") & (ch <= "f") THEN RETURN ORD( ch ) - ORD( "a" ) + 10
-				ELSE Error( Basic.NumberIllegalCharacter );  RETURN 0
-				END
-			END Hexadecimal;
-
-		BEGIN
-			result := Number;
-			IF (ch = "0") THEN
-				IF reader.Peek() = "x" THEN (* hex number *)
-					digits := 0;
-					GetNextCharacter; GetNextCharacter;
-					WHILE (ch >= "0") & (ch <= "9") OR (ch >= "a") & (ch <="f") DO
-						number := number * 10H + Hexadecimal(ch);
-						INC(digits);
-						GetNextCharacter;
-					END;
-					symbol.hugeint := number;
-					symbol.integer := SHORT(number);
-					IF digits > MaxHexDigits THEN
-						symbol.numberType := Hugeint
-					ELSE
-						symbol.numberType := Integer
-					END;
-				ELSIF reader.Peek() = "b" THEN (* binary number *)
-					digits := 0;
-					GetNextCharacter; GetNextCharacter;
-					WHILE (ch >= "0") & (ch <= "1") DO
-						number := number * 2;
-						INC(digits);
-						IF ch = "1" THEN INC(number) END;
-						GetNextCharacter;
-					END;
-					symbol.hugeint := number;
-					symbol.integer := SHORT(number);
-					IF digits > 32 THEN
-						symbol.numberType := Hugeint
-					ELSE
-						symbol.numberType := Integer
-					END;
-				ELSE RETURN GetNumber^(symbol)
-				END;
-			ELSE RETURN GetNumber^(symbol)
-			END;
-			RETURN result
-		END GetNumber;
-
 		(** get next symbol **)
 		PROCEDURE GetNextSymbol*(VAR symbol: Symbol ): BOOLEAN;
 		VAR s: LONGINT;