Browse Source

окончательно переделал структуру каталогов, исправил баг с зацикливанием
для fw начал портировать YSon, реализовал Log.Tab

p.kushnir 10 years ago
parent
commit
a86809aaef

BIN
Docu/Tool-Map.odc


BIN
Mod/Dump.odc


BIN
Mod/TestEnv.odc


+ 258 - 0
Src/JSon/Mod/Formatter.cp

@@ -0,0 +1,258 @@
+MODULE JSonFormatter;
+	
+(**
+	project	= "JSon"
+	organization	= ""
+	contributors	= ""
+	version	= "System/Rsrc/About"
+	copyright	= "Kushnir Piotr Michailovich"
+	license	= "Docu/BB-License"
+	purpose	= "генерация json вручную, этот способ полезен тем, кто не использует YSonModels, по каким-то причинам"
+	changes	= "
+	- 20130112, pk, автогенерация заголовка
+	- 20150204, pk, порт для fw
+"
+	issues	= ""
+**)
+	
+	IMPORT
+		JSonGenerator,
+		Str;
+	
+	CONST
+		objBegin* = 1;
+		objEnd* = 2;
+		arrBegin* = 3;
+		arrEnd* = 4;
+		name = 5;
+		value = 6;
+		
+		stringVal* = 1;
+		unicodeStringVal* = 10;
+		intVal* = 2;
+		realVal* =3;
+		atomVal*= 4;
+		
+		errWrongSym* = -1;
+		errUnexpected* = -2;
+		
+	TYPE
+		Formatter* = POINTER TO ABSTRACT RECORD END;
+		
+		Directory* = POINTER TO ABSTRACT RECORD END;
+		
+		StdDir = POINTER TO RECORD (Directory) END;
+		
+		StdF = POINTER TO RECORD (Formatter) 
+			wr: JSonGenerator.Writer;
+			this: StackItem;
+		END;
+		
+		StackItem = POINTER TO RECORD
+			depth: INTEGER;
+			expect: SET;
+			values: LONGINT;
+			next: StackItem;
+		END;
+		
+	VAR 
+		dir-, prev-, stdDir-: Directory;
+		
+	PROCEDURE (d: Directory) New* (wr: JSonGenerator.Writer): Formatter, NEW, ABSTRACT;
+	
+	PROCEDURE (f: Formatter) ConnectTo- (wr: JSonGenerator.Writer), NEW, ABSTRACT;
+	PROCEDURE (f: Formatter) WriteSym* (sym: INTEGER; OUT res: INTEGER), NEW, ABSTRACT;
+	PROCEDURE (f: Formatter) WriteName* (IN s: ARRAY OF CHAR; OUT res: INTEGER), NEW, ABSTRACT;
+	PROCEDURE (f: Formatter) WriteValue* (type: INTEGER; IN val: ARRAY OF CHAR; OUT res: INTEGER), NEW, ABSTRACT;
+	
+	PROCEDURE NewStackItem(): StackItem;
+		VAR s: StackItem;
+	BEGIN
+		NEW(s);
+		s.depth:=1;
+		s.expect:={};
+		s.values:=0;
+	RETURN s;
+	END NewStackItem;
+	
+	PROCEDURE Push(VAR root: StackItem);
+		VAR new: StackItem;
+	BEGIN
+		new:=NewStackItem();
+		new.next:=root;
+		root:=new;
+		IF root.next#NIL THEN root.depth:=root.next.depth+1 END
+	END Push;
+	
+	PROCEDURE Pop(VAR root: StackItem);
+		VAR old: StackItem;
+	BEGIN
+		IF root#NIL THEN
+			old:=root;
+			root:=old.next;
+			old:=NIL;
+		END;
+	END Pop;
+	
+	PROCEDURE (f: StdF) ConnectTo (wr: JSonGenerator.Writer);
+	BEGIN
+		ASSERT(wr#NIL, 20); ASSERT(wr.Base()#NIL, 21);
+		f.wr:=wr;
+		f.this:=NIL;
+	END ConnectTo;
+	
+	PROCEDURE String (wr: JSonGenerator.Writer; IN s: ARRAY OF CHAR);
+		VAR i: INTEGER;
+	BEGIN
+		i:=0;
+		WHILE i<LEN(s$) DO
+			CASE s[i] OF
+				'"': wr.Char('\'); wr.Char('"');
+				|'\': wr.Char('\'); wr.Char('\');
+				|09X: wr.Char('\'); wr.Char('t');
+				|0DX: wr.Char('\'); wr.Char('r');
+				|0AX: wr.Char('\'); wr.Char('n');
+				|0CX: wr.Char('\'); wr.Char('f');
+				|08X: wr.Char('\'); wr.Char('b');
+			ELSE wr.Char(s[i]) END;
+			INC(i)
+		END;
+	END String;
+	
+	PROCEDURE UniString (wr: JSonGenerator.Writer; IN s: ARRAY OF CHAR);
+		VAR i: INTEGER;
+	BEGIN
+		i:=0;
+		WHILE i<LEN(s$) DO
+			CASE s[i] OF
+				'"': wr.Char('\'); wr.Char('"');
+				|'\': wr.Char('\'); wr.Char('\');
+				|09X: wr.Char('\'); wr.Char('t');
+				|0DX: wr.Char('\'); wr.Char('r');
+				|0AX: wr.Char('\'); wr.Char('n');
+				|0CX: wr.Char('\'); wr.Char('f');
+				|08X: wr.Char('\'); wr.Char('b');
+			ELSE wr.UnicodeChar(s[i]) END;
+			INC(i)
+		END;
+	END UniString;
+	
+	PROCEDURE (f: StdF) WriteName (IN s: ARRAY OF CHAR; OUT res: INTEGER);
+		VAR i: INTEGER;
+	BEGIN
+		ASSERT(s$#'', 20);
+		res:=0;
+		IF (f.this#NIL) & (name IN f.this.expect) THEN
+			IF (objEnd IN f.this.expect) THEN 
+				IF f.this.values > 0 THEN 
+					f.wr.Char(','); 
+					f.wr.Whitespace(0DX);
+				END;
+				FOR i:=1 TO f.this.depth DO f.wr.Whitespace(09X) END;
+			END;
+			f.wr.Char('"'); String(f.wr, s); f.wr.Char('"'); f.wr.Char(':'); f.wr.Whitespace(' '); f.this.expect:={value, arrBegin, objBegin};
+			INC(f.this.values);
+		ELSE
+			res:=errUnexpected
+		END;
+	END WriteName;
+	
+	PROCEDURE (f: StdF) WriteValue (type: INTEGER; IN v: ARRAY OF CHAR; OUT res: INTEGER);
+		VAR i: INTEGER; vs: ARRAY 20 OF CHAR;
+	BEGIN
+		ASSERT(type IN {stringVal, atomVal, intVal, realVal, unicodeStringVal}, 20);
+		ASSERT((type IN {stringVal, unicodeStringVal}) OR (v$#''), 21); 
+		res:=0;
+		IF (f.this#NIL) & (value IN f.this.expect) THEN
+			IF (arrEnd IN f.this.expect) THEN
+				IF f.this.values > 0 THEN 
+					f.wr.Char(','); 
+					f.wr.Whitespace(0DX);
+				END;
+				FOR i:=1 TO f.this.depth DO f.wr.Whitespace(09X) END;
+			END;
+			CASE type OF
+				stringVal: f.wr.Char('"'); String(f.wr, v); f.wr.Char('"');
+				|unicodeStringVal: f.wr.Char('"'); UniString(f.wr, v); f.wr.Char('"');
+				|intVal, realVal: String(f.wr, v);
+				|atomVal: Str.ToLower(v, vs); String(f.wr, vs); (* null, true, false точно поместятся в 20 символов *)
+			ELSE HALT(100) END;	
+			INC(f.this.values);
+			IF ~(arrEnd IN f.this.expect) THEN f.this.expect:={objEnd, name} END;
+		ELSE
+			res:=errUnexpected
+		END;
+	END WriteValue;
+	
+	PROCEDURE (f: StdF) WriteSym (sym: INTEGER; OUT res: INTEGER);
+		VAR expect: SET; i: INTEGER;
+	BEGIN
+		res:=0;
+		IF f.this#NIL THEN expect:=f.this.expect ELSE expect:={objBegin, arrBegin} END;
+		IF (sym IN expect) THEN
+			CASE sym OF
+				objBegin: 
+					IF (f.this#NIL) THEN
+						IF ~(arrEnd IN f.this.expect) THEN 
+							f.this.expect:={objEnd, name} 
+						ELSE
+							IF f.this.values > 0 THEN 
+								f.wr.Char(','); 
+								f.wr.Whitespace(0DX);
+							END;
+							FOR i:=1 TO f.this.depth DO f.wr.Whitespace(09X) END;
+						END;
+					END;
+					Push(f.this); f.wr.Char('{'); f.wr.Whitespace(0DX); f.this.expect:={objEnd, name}
+				|arrBegin: 
+					IF (f.this#NIL) THEN
+						IF ~(arrEnd IN f.this.expect) THEN f.this.expect:={objEnd, name} 
+						ELSE
+							IF f.this.values > 0 THEN 
+								f.wr.Char(','); 
+								f.wr.Whitespace(0DX);
+							END;
+							FOR i:=1 TO f.this.depth DO f.wr.Whitespace(09X) END;
+						END;
+					END;
+					Push(f.this); f.wr.Char('['); f.wr.Whitespace(0DX); f.this.expect:={arrEnd, objBegin, arrBegin, value}
+				|objEnd: 
+					f.wr.Whitespace(0DX); FOR i:=1 TO f.this.depth-1 DO f.wr.Whitespace(09X) END;
+					f.wr.Char('}'); Pop(f.this);
+				|arrEnd: 
+					f.wr.Whitespace(0DX); FOR i:=1 TO f.this.depth-1 DO f.wr.Whitespace(09X) END; 
+					f.wr.Char(']'); Pop(f.this)
+			ELSE HALT(100) END;
+		ELSE
+			res:=errWrongSym;
+			HALT(100);
+		END;
+	END WriteSym;
+	
+	PROCEDURE (d: StdDir) New (wr: JSonGenerator.Writer): Formatter;
+		VAR f: StdF;
+	BEGIN
+		ASSERT(wr#NIL, 20); ASSERT(wr.Base()#NIL, 21);
+		NEW(f);
+		f.ConnectTo(wr);
+	RETURN f
+	END New;
+	
+	PROCEDURE Install* (d: Directory);
+	BEGIN
+		ASSERT(d#NIL, 20);
+		prev:=dir;
+		dir:=d;
+	END Install;
+	
+	PROCEDURE Init;
+		VAR d: StdDir;
+	BEGIN
+		NEW(d);
+		Install(d);
+		stdDir:=d;
+	END Init;
+	
+BEGIN
+	Init
+END JSonFormatter.

+ 48 - 0
Src/JSon/Mod/Generator.cp

@@ -0,0 +1,48 @@
+MODULE JSonGenerator;
+(**
+	project	= "JSon"
+	organization	= ""
+	contributors	= ""
+	version	= "System/Rsrc/About"
+	copyright	= "Kushnir Piotr Michailovich"
+	license	= "Docu/BB-License"
+	purpose	= "Реализация генератора"
+	changes	= "
+	- 20130102, pk, автогенерация заголовка
+"
+	issues	= "-
+	 20150204, порт для fw
+	"
+**)
+	
+	IMPORT 
+		Str;
+		
+	TYPE
+		Writer* = POINTER TO ABSTRACT RECORD 
+			base: ANYPTR;
+		END;
+		
+	PROCEDURE (w: Writer) Whitespace* (s: ARRAY OF CHAR), NEW, EMPTY;
+	PROCEDURE (w: Writer) Char* (ch: CHAR), NEW, ABSTRACT;
+	
+	PROCEDURE (w: Writer) UnicodeChar* (ch: CHAR), NEW, EXTENSIBLE;
+		VAR x: INTEGER; vs: ARRAY 12 OF CHAR;
+	BEGIN
+		x:=ORD(ch);
+		Str.IntToStringForm(x, Str.hexadecimal, 4, '0', Str.hideBase, vs);
+		w.Char('\'); w.Char('u'); w.Char(vs[0]); w.Char(vs[1]); w.Char(vs[2]); w.Char(vs[3]);  
+	END UnicodeChar;
+	
+	PROCEDURE (w: Writer) Base* (): ANYPTR, NEW;
+	BEGIN
+		RETURN w.base;
+	END Base;
+	
+	PROCEDURE (w: Writer) SetBase* (base: ANYPTR), NEW, EXTENSIBLE;
+	BEGIN
+		ASSERT(base#NIL, 20);
+		w.base:=base;
+	END SetBase;
+	
+END JSonGenerator.

+ 77 - 0
Src/JSon/Mod/ObxNoModel.cp

@@ -0,0 +1,77 @@
+MODULE JSonObxNoModel;
+(**
+	project	= "YSon"
+	organization	= ""
+	contributors	= ""
+	version	= "System/Rsrc/About"
+	copyright	= "Kushnir Piotr Michailovich"
+	license	= "Docu/BB-License"
+	purpose	= "демонстрация работы форматтера  без использования динамических моделей данных"
+	changes	= "
+	- 20130527, pk, автогенерация заголовка, документирование
+	- 20150204, pk, порт для fw
+"
+	issues	= ""
+**)
+
+
+	IMPORT 
+		Gen:=JSonGenerator, F:=JSonFormatter,
+		Out;
+	
+	TYPE
+		Writer = POINTER TO RECORD (Gen.Writer) END; (* дефолтный вывод - в лог *)
+		
+	PROCEDURE (w: Writer) Char (c: CHAR);
+	BEGIN
+		Out.Char(c);
+	END Char;
+	
+	PROCEDURE (w: Writer) Whitespace (s: ARRAY OF CHAR);
+	BEGIN
+		CASE s[0] OF
+		09X: Out.Tab;
+		|0DX, 0AX: Out.Ln;
+		|' ': Out.Char(' ');
+		ELSE Out.String(s$) END
+	END Whitespace;
+
+	(* формирование структуры JSON непосредственно при выполнении комманд форматтера *)
+	PROCEDURE Do*;
+		TYPE Base = POINTER TO RECORD END;
+		VAR b: Base; wr: Writer; f: F.Formatter; res: INTEGER;
+	BEGIN
+		Out.Ln;
+		NEW(wr); 
+		NEW(b);
+		wr.SetBase(b);
+		f:=F.dir.New(wr);
+(* демонстрация пошагового результата *)
+		f.WriteSym(F.arrBegin, res);	(* [ *)
+		f.WriteSym(F.objBegin, res);		(* { *)
+		f.WriteName('obj', res);			(* "obj" *)
+		f.WriteSym(F.objBegin, res);			(* { *)
+		f.WriteSym(F.objEnd, res);			(* } *)
+		f.WriteName('arr', res);			(* "arr" *)
+		f.WriteSym(F.arrBegin, res);				(* [ *)
+		f.WriteValue(F.atomVal, 'true', res);					(* true *)
+		f.WriteValue(F.atomVal, 'true', res);					(* true *)
+		f.WriteValue(F.atomVal, 'true', res);					(* true *)
+		f.WriteSym(F.objBegin, res);					(* { *)
+		f.WriteSym(F.objEnd, res);					(* } *)
+		f.WriteSym(F.arrBegin, res);					(* [ *)
+		f.WriteSym(F.arrEnd, res);					(* ] *)
+		f.WriteSym(F.arrEnd, res);				(* ] *)
+		f.WriteName('sss', res);			(* "sss" *)
+		f.WriteValue(F.atomVal, 'true', res);			(* true *)
+		f.WriteName('sss1', res);			(* "sss1" *)
+		f.WriteValue(F.stringVal, 'hello, world!', res);			(* "hello, world!" *)
+		f.WriteSym(F.objEnd, res);		(* } *)
+		f.WriteSym(F.arrEnd, res);	(* ] *)
+	END Do;
+	
+BEGIN
+
+END JSonObxNoModel.
+
+(*JediPlain*gvFEZXZDb21tYW5kZXJzLlN0ZFZpZXdEZXNjAPFEZXZDb21tYW5kZXJzLlZpZXdEZXNjAPFWaWV3cy5WaWV3RGVzYwDwU3RvcmVzLlN0b3JlRGVzYwAAAAAAAAAAAAAAAAAGAAAAAAAAFQAA*)YSonObxNoModel.Do

+ 1 - 1
Src/System/Mod/Cons.cp

@@ -79,7 +79,7 @@ MODULE Cons;
 	
 	PROCEDURE (log: Hook) Tab;
 	BEGIN
-	
+		Console.Tab;
 	END Tab;
 	
 	PROCEDURE (log: Hook) Ln;

+ 5 - 0
Src/System/Mod/Console.cp

@@ -31,5 +31,10 @@ MODULE Console;
 		String("\n")
 	END Ln;
 	
+	PROCEDURE Tab*;
+	BEGIN
+		String("\t")
+	END Tab;
+	
 END Console.
 

+ 1 - 0
Src/System/Mod/Start.cp

@@ -7,4 +7,5 @@ BEGIN
 	Core.LoadMod("TestMath");
 	Core.LoadMod("TestStrings");
 	Core.LoadMod("TestStrDyn");
+	Core.LoadMod("Start3");
 END Start.

+ 7 - 0
Src/System/Mod/Start3.cp

@@ -0,0 +1,7 @@
+MODULE Start3;
+	
+	IMPORT JSonObxNoModel;
+
+BEGIN
+	JSonObxNoModel.Do
+END Start3.

+ 127 - 5
Src/System/Mod/Str.cp

@@ -7,7 +7,9 @@ MODULE Str;
 	CONST
 		minLongIntRev = "8085774586302733229";	(* reversed string of -MIN(LONGINT) *)
 		digitspace* = 08FX;
-	
+		charCode* = -1; decimal* = 10; hexadecimal* = -2; roman*= -3;
+		showBase* = TRUE; hideBase* = FALSE;
+		
 	TYPE
 		Dyn* = POINTER TO LIMITED RECORD 
 			x: POINTER TO ARRAY OF CHAR;
@@ -17,7 +19,9 @@ MODULE Str;
 		maxExp: INTEGER;
 		maxDig: INTEGER;
 		factor: REAL;	(* 10^maxDig *)	
-	
+		digits: ARRAY 17 OF CHAR;
+		toUpper, toLower: ARRAY 256 OF CHAR;
+		
 	PROCEDURE New*(): Dyn;
 		VAR d: Dyn;
 	BEGIN
@@ -43,6 +47,16 @@ MODULE Str;
 		d.x[next]:=c
 	END Add;
 	
+	PROCEDURE (d: Dyn) CopyOf*(): POINTER TO ARRAY OF CHAR, NEW;
+		VAR tmp, new: POINTER TO ARRAY OF CHAR;
+	BEGIN
+		tmp:=d.x;
+		d.Add(0X);
+		new:=d.x;
+		d.x:=tmp;
+	RETURN new;
+	END CopyOf;
+	
 	(* integer conversions *)
 
 	PROCEDURE IntToString* (x: LONGINT; OUT s: ARRAY OF CHAR);
@@ -60,6 +74,93 @@ MODULE Str;
 		s[k] := 0X
 	END IntToString;
 	
+	PROCEDURE IntToStringForm* (x: LONGINT; form, minWidth: INTEGER; fillCh: CHAR;
+														showBase: BOOLEAN; OUT s: ARRAY OF CHAR);
+		VAR base, i, j, k, si: INTEGER; mSign: BOOLEAN; a: ARRAY 128 OF CHAR; c1, c5, c10: CHAR;
+	BEGIN
+		ASSERT((form = charCode) OR (form = hexadecimal) OR (form = roman) OR ((form >= 2) & (form <= 16)), 20);
+		ASSERT(minWidth >= 0, 22);
+		IF form = charCode THEN base := 16
+		ELSIF form = hexadecimal THEN base := 16
+		ELSE base := form
+		END;
+		
+		IF form = roman THEN
+			ASSERT((x > 0) & (x < 3999), 21); 
+			base := 1000; i := 0; mSign := FALSE;
+			WHILE (base > 0) & (x > 0) DO
+				IF base = 1 THEN c1 := "I"; c5 := "V"; c10 := "X"
+				ELSIF base = 10 THEN c1 := "X"; c5 := "L"; c10 := "C"
+				ELSIF base = 100 THEN c1 := "C"; c5 := "D"; c10 := "M"
+				ELSE c1 := "M"
+				END;
+				k := SHORT(x DIV base); x := x MOD base;
+				IF k IN {4, 9} THEN a[i] := c1; INC(i) END;
+				IF k IN {4 .. 8} THEN a[i] := c5; INC(i) END;
+				IF k = 9 THEN a[i] := c10; INC(i)
+				ELSIF k IN {1 .. 3, 6 .. 8} THEN
+					j := k MOD 5;
+					REPEAT a[i] := c1; INC(i); DEC(j) UNTIL j = 0
+				END;
+				base := base DIV 10
+			END
+		ELSIF (form = hexadecimal) OR (form = charCode) THEN
+			i := 0; mSign := FALSE;
+			IF showBase THEN DEC(minWidth) END;
+			REPEAT
+				a[i] := digits[x MOD base]; x := x DIV base; INC(i)
+			UNTIL (x = 0) OR (x = -1) OR (i = LEN(a));
+			IF x = -1 THEN fillCh := "F" END
+		ELSE
+			IF x < 0 THEN
+				i := 0; mSign := TRUE; DEC(minWidth);
+				REPEAT
+					IF x MOD base = 0 THEN
+						a[i] := digits[0]; x := x DIV base
+					ELSE
+						a[i] := digits[base - x MOD base]; x := x DIV base + 1
+					END;
+					INC(i)
+				UNTIL (x = 0) OR (i = LEN(a))
+			ELSE
+				i := 0; mSign := FALSE;
+				REPEAT
+					a[i] := digits[x MOD base]; x := x DIV base; INC(i)
+				UNTIL (x = 0) OR (i = LEN(a))
+			END;
+			IF showBase THEN DEC(minWidth);
+				IF base < 10 THEN DEC(minWidth) ELSE DEC(minWidth,2) END
+			END
+		END;
+		si := 0;
+		IF mSign & (fillCh = "0") & (si < LEN(s)) THEN s[si] := "-"; INC(si); mSign := FALSE END;
+		WHILE minWidth > i DO
+			IF si < LEN(s) THEN s[si] := fillCh; INC(si) END;
+			DEC(minWidth)
+		END;
+		IF mSign & (si < LEN(s)) THEN s[si] := "-"; INC(si) END;
+		IF form = roman THEN
+			j := 0;
+			WHILE j < i DO 
+				IF si < LEN(s) THEN s[si] := a[j]; INC(si) END; 
+				INC(j)
+			END
+		ELSE
+			REPEAT DEC(i);
+				IF si < LEN(s) THEN s[si] := a[i]; INC(si) END
+			UNTIL i = 0
+		END;
+		IF showBase & (form # roman) THEN
+			IF (form = charCode) & (si < LEN(s)) THEN s[si] := "X"; INC(si)
+			ELSIF (form = hexadecimal) & (si < LEN(s)) THEN s[si] := "H"; INC(si)
+			ELSIF (form < 10) & (si < LEN(s)-1) THEN s[si] := "%"; s[si+1] := digits[base]; INC(si, 2)
+			ELSIF (si < LEN(s) - 2) THEN
+				s[si] := "%"; s[si+1] := digits[base DIV 10]; s[si+2] := digits[base MOD 10]; INC(si, 3)
+			END
+		END;
+		IF si < LEN(s) THEN s[si] := 0X ELSE HALT(23) END
+	END IntToStringForm;
+	
 		(* real conversions *)
 
 	PROCEDURE RealToStringForm* (x: REAL; precision, minW, expW: INTEGER; fillCh: CHAR;
@@ -169,8 +270,29 @@ MODULE Str;
 		RealToStringForm(x, 16, 0, 0, digitspace, s)
 	END RealToString;
 	
+	PROCEDURE ToLower* (in: ARRAY OF CHAR; OUT out: ARRAY OF CHAR);
+		VAR i, max: INTEGER;
+	BEGIN i := 0; max := LEN(out)-1;
+		WHILE (in[i] # 0X) & (i < max) DO
+			IF ORD(in[i]) < 256 THEN out[i] := toLower[ORD(in[i])] ELSE out[i] := in[i] END;
+			INC(i)
+		END;
+		out[i] := 0X
+	END ToLower;
+	
+	PROCEDURE Init;
+		VAR i: INTEGER;
+	BEGIN
+		maxExp := SHORT(ENTIER(Mathe.Log(MAX(REAL)))) + 1;	
+		maxDig := SHORT(ENTIER(-Mathe.Log(Mathe.Eps())));
+		factor := Mathe.IntPower(10, maxDig);
+		digits := "0123456789ABCDEF"; 
+		FOR i := 0 TO 255 DO toUpper[i] :=  CHR(i); toLower[i] := CHR(i) END;
+		FOR i := ORD("A") TO ORD("Z") DO toLower[i] := CHR(i + 32); toUpper[i + 32] := CHR(i) END;
+		FOR i := ORD("À") TO ORD ("Ö") DO toLower[i] := CHR(i + 32); toUpper[i + 32] := CHR(i) END;
+		FOR i := ORD("Ø") TO ORD ("Þ") DO toLower[i] := CHR(i + 32); toUpper[i + 32] := CHR(i) END;
+	END Init;
+	
 BEGIN
-	maxExp := SHORT(ENTIER(Mathe.Log(MAX(REAL)))) + 1;	
-	maxDig := SHORT(ENTIER(-Mathe.Log(Mathe.Eps())));
-	factor := Mathe.IntPower(10, maxDig)
+	Init
 END Str.

+ 4 - 2
Src/Test/Mod/A0.cp

@@ -1,6 +1,6 @@
 MODULE TestA0;
 
-	IMPORT Log:=Out, Core;
+	IMPORT Log:=Out, Core, Str;
 	
 	TYPE
 		Item = POINTER TO RECORD
@@ -36,11 +36,13 @@ MODULE TestA0;
 	END Do;
 	
 	PROCEDURE Do0;
-		VAR p: Item;
+		VAR p: Item; vs: ARRAY 15 OF CHAR;
 	BEGIN
 		IF p#NIL THEN
 			p.next:=NIL (* NIL trap here? *)
 		END;
+		Str.IntToStringForm(505, Str.hexadecimal, 4, '0', Str.hideBase, vs);
+		Log.String("IntToStringForm "); Log.String(vs); Log.Ln;
 	END Do0;
 	
 	PROCEDURE Do1;

+ 1 - 0
Src/Test/Mod/StrDyn.cp

@@ -13,6 +13,7 @@ MODULE TestStrDyn;
 			INC(i);
 		END;
 		Out.Ln;
+		Out.String(d.CopyOf()$); Out.Ln;
 	END Init;
 	
 BEGIN

BIN
Src/Xev/Docu/Tool-Map.odc


+ 0 - 0
Docu/ast.odt → Src/Xev/Docu/ast.odt


+ 0 - 0
Docu/ast.pdf → Src/Xev/Docu/ast.pdf


+ 0 - 0
Mod/Compiler.odc → Src/Xev/Mod/Compiler.odc


+ 0 - 0
Mod/Const.odc → Src/Xev/Mod/Const.odc


BIN
Src/Xev/Mod/Dump.odc


BIN
Src/Xev/Mod/TestEnv.odc


+ 0 - 0
Mod/TestEnv0.odc → Src/Xev/Mod/TestEnv0.odc


+ 0 - 0
Rsrc/Menus.odc → Src/Xev/Rsrc/Menus.odc