MODULE============; IMPORT SynLocation, Text, ObLib, ObValue, Obliq, Rd, Wr, Process, FloatMode, Thread, Stdio, Pipe, FileRd, FileWr, OSError, Fmt, Lex, TextRd, TextWr, NetObj, Pickle2 AS Pickle, Word, SharedObj, Random; VAR setupDone := FALSE; PROCEDURE ObLibM3 PackageSetup () = BEGIN IF NOT setupDone THEN setupDone := TRUE; Setup(); END; END PackageSetup; PROCEDURESetup () = BEGIN SetupRd(); SetupWr(); SetupLex(); SetupFmt(); SetupWord(); SetupPickle(); SetupProc(); SetupRandom(); END Setup;
rd
package ============
TYPE RdCode = {Failure, EofFailure, New, Stdin, Open, GetChar, Eof, UnGetChar, CharsReady, GetText, GetLine, Index, Length, Seek, Close, Intermittent, Seekable, Closed}; RdOpCode = ObLib.OpCode OBJECT code: RdCode; END; PackageRd = ObLib.T OBJECT OVERRIDES Eval:=EvalRd; END; PROCEDURE============IsRd (self: ValRd; other: ObValue.ValAnything): BOOLEAN = BEGIN TYPECASE other OF ValRd(oth)=> RETURN self.rd = oth.rd; ELSE RETURN FALSE END; END IsRd; PROCEDURECopyRd (self: ObValue.ValAnything; <*UNUSED*>tbl: ObValue.Tbl; <*UNUSED*>loc: SynLocation.T): ObValue.ValAnything = BEGIN RETURN self; END CopyRd; VAR rdFailureException, rdEofFailureException: ObValue.ValException; PROCEDURENewRdOC (name: TEXT; arity: INTEGER; code: RdCode) : RdOpCode = BEGIN RETURN NEW(RdOpCode, name:=name, arity:=arity, code:=code); END NewRdOC; VAR true, false: ObValue.ValBool; PROCEDURESetupRd () = TYPE OpCodes = ARRAY OF ObLib.OpCode; VAR opCodes: REF OpCodes; BEGIN opCodes := NEW(REF OpCodes, NUMBER(RdCode)); opCodes^ := OpCodes{ NewRdOC("failure", -1, RdCode.Failure), NewRdOC("eofFailure", -1, RdCode.EofFailure), NewRdOC("new", 1, RdCode.New), NewRdOC("stdin", -1, RdCode.Stdin), NewRdOC("open", 2, RdCode.Open), NewRdOC("getChar", 1, RdCode.GetChar), NewRdOC("eof", 1, RdCode.Eof), NewRdOC("unGetChar", 1, RdCode.UnGetChar), NewRdOC("charsReady", 1, RdCode.CharsReady), NewRdOC("getText", 2, RdCode.GetText), NewRdOC("getLine", 1, RdCode.GetLine), NewRdOC("index", 1, RdCode.Index), NewRdOC("length", 1, RdCode.Length), NewRdOC("seek", 2, RdCode.Seek), NewRdOC("close", 1, RdCode.Close), NewRdOC("intermittent", 1, RdCode.Intermittent), NewRdOC("seekable", 1, RdCode.Seekable), NewRdOC("closed", 1, RdCode.Closed) }; ObLib.Register( NEW(PackageRd, name:="rd", opCodes:=opCodes)); rdFailureException := NEW(ObValue.ValException, name:="rd_failure"); rdEofFailureException := NEW(ObValue.ValException, name:="rd_eofFailure"); true := NEW(ObValue.ValBool, bool:=TRUE); false := NEW(ObValue.ValBool, bool:=FALSE); END SetupRd; PROCEDUREEvalRd (self: PackageRd; opCode: ObLib.OpCode; <*UNUSED*>arity: ObLib.OpArity; READONLY args: ObValue.ArgArray; temp: BOOLEAN; loc: SynLocation.T) : ObValue.Val RAISES {ObValue.Error, ObValue.Exception} = VAR rd1: Rd.T; text1: TEXT; int1: INTEGER := 0; fileSys1: ObValue.ValFileSystem; BEGIN TRY CASE NARROW(opCode, RdOpCode).code OF | RdCode.Failure => RETURN rdFailureException; | RdCode.EofFailure => RETURN rdEofFailureException; | RdCode.New => TYPECASE args[1] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(1, "text", self.name, opCode.name, loc); <*ASSERT FALSE*> END; rd1 := TextRd.New(text1); RETURN NEW(ValRd, what:="<a reader>", tag:="Reader", picklable:=FALSE, rd:=rd1); | RdCode.Stdin => RETURN NEW(ValRd, what:="<stdin reader>", tag:="Reader", picklable:=FALSE, rd:=Stdio.stdin); | RdCode.Open => TYPECASE args[1] OF | ObValue.ValFileSystem(node) => fileSys1:=node; ELSE ObValue.BadArgType(1, "file system", self.name, opCode.name, loc); <*ASSERT FALSE*> END; TYPECASE args[2] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(2, "text", self.name, opCode.name, loc); <*ASSERT FALSE*> END; rd1 := fileSys1.remote.OpenRead(text1); RETURN NEW(ValRd, what:="<'" & text1 & "' reader>", tag := "Reader", picklable:=FALSE, rd:=rd1); | RdCode.GetChar => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; RETURN NEW(ObValue.ValChar, char:=Rd.GetChar(rd1)); | RdCode.Eof => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.EOF(rd1) THEN RETURN true ELSE RETURN false END; | RdCode.UnGetChar => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; Rd.UnGetChar(rd1); RETURN ObValue.valOk; | RdCode.CharsReady => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; RETURN NEW(ObValue.ValInt, int:=Rd.CharsReady(rd1), temp:=temp); | RdCode.GetText => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; TYPECASE args[2] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF int1<0 THEN ObValue.BadArgVal(2, "non-negative", self.name, opCode.name,loc); <*ASSERT FALSE*> END; RETURN ObValue.NewText(Rd.GetText(rd1, int1)); | RdCode.GetLine => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; RETURN ObValue.NewText(Rd.GetLine(rd1)); | RdCode.Index => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; RETURN NEW(ObValue.ValInt, int:=Rd.Index(rd1), temp:=temp); | RdCode.Length => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Intermittent(rd1) THEN ObValue.BadArgVal(1,"non-intermittent",self.name, opCode.name,loc); <*ASSERT FALSE*> END; RETURN NEW(ObValue.ValInt, int:=Rd.Length(rd1), temp:=temp); | RdCode.Seek => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; TYPECASE args[2] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF NOT Rd.Seekable(rd1) THEN ObValue.BadArgVal(1, "seekable", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF int1<0 THEN ObValue.BadArgVal(2,"non-negative", self.name, opCode.name, loc); <*ASSERT FALSE*> END; Rd.Seek(rd1, int1); RETURN ObValue.valOk; | RdCode.Close => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; Rd.Close(rd1); RETURN ObValue.valOk; | RdCode.Intermittent => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Intermittent(rd1) THEN RETURN true ELSE RETURN false END; | RdCode.Seekable => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Seekable(rd1) THEN RETURN true ELSE RETURN false END; | RdCode.Closed => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*> END; IF Rd.Closed(rd1) THEN RETURN true ELSE RETURN false END; ELSE ObValue.BadOp(self.name, opCode.name, loc);<*ASSERT FALSE*> END; EXCEPT | Rd.Failure, ObValue.ServerError => ObValue.RaiseException(rdFailureException, self.name & "_" & opCode.name, loc); <*ASSERT FALSE*> | Rd.EndOfFile => ObValue.RaiseException(rdEofFailureException, self.name & "_" & opCode.name, loc); <*ASSERT FALSE*> | Thread.Alerted => ObValue.RaiseException(ObValue.threadAlerted, self.name&"_"&opCode.name, loc); <*ASSERT FALSE*> | NetObj.Error(atoms) => ObValue.RaiseNetException(self.name&"_"&opCode.name, atoms, loc); <*ASSERT FALSE*> END; END EvalRd;
wr
package ============
TYPE WrCode = {Failure, New, Stdout, Stderr, Open, OpenAppend, ToText, PutChar, PutText, Flush, Index, Length, Seek, Close, Buffered, Seekable, Closed}; WrOpCode = ObLib.OpCode OBJECT code: WrCode; END; PackageWr = ObLib.T OBJECT OVERRIDES Eval:=EvalWr; END; PROCEDURE============IsWr (self: ValWr; other: ObValue.ValAnything): BOOLEAN = BEGIN TYPECASE other OF ValWr(oth)=> RETURN self.wr = oth.wr; ELSE RETURN FALSE END; END IsWr; PROCEDURECopyWr (self: ObValue.ValAnything; <*UNUSED*>tbl: ObValue.Tbl; <*UNUSED*>loc: SynLocation.T): ObValue.ValAnything = BEGIN RETURN self; END CopyWr; VAR wrFailureException: ObValue.ValException; PROCEDURENewWrOC (name: TEXT; arity: INTEGER; code: WrCode) : WrOpCode = BEGIN RETURN NEW(WrOpCode, name:=name, arity:=arity, code:=code); END NewWrOC; PROCEDURESetupWr () = TYPE OpCodes = ARRAY OF ObLib.OpCode; VAR opCodes: REF OpCodes; BEGIN opCodes := NEW(REF OpCodes, NUMBER(WrCode)); opCodes^ := OpCodes{ NewWrOC("failure", -1, WrCode.Failure), NewWrOC("new", 0, WrCode.New), NewWrOC("stdout", -1, WrCode.Stdout), NewWrOC("stderr", -1, WrCode.Stderr), NewWrOC("open", 2, WrCode.Open), NewWrOC("openAppend", 2, WrCode.OpenAppend), NewWrOC("toText", 1, WrCode.ToText), NewWrOC("putChar", 2, WrCode.PutChar), NewWrOC("putText", 2, WrCode.PutText), NewWrOC("flush", 1, WrCode.Flush), NewWrOC("index", 1, WrCode.Index), NewWrOC("length", 1, WrCode.Length), NewWrOC("seek", 2, WrCode.Seek), NewWrOC("close", 1, WrCode.Close), NewWrOC("buffered", 1, WrCode.Buffered), NewWrOC("seekable", 1, WrCode.Seekable), NewWrOC("closed", 1, WrCode.Closed) }; ObLib.Register( NEW(PackageWr, name:="wr", opCodes:=opCodes)); wrFailureException := NEW(ObValue.ValException, name:="wr_failure"); END SetupWr; PROCEDUREEvalWr (self: PackageWr; opCode: ObLib.OpCode; <*UNUSED*>arity: ObLib.OpArity; READONLY args: ObValue.ArgArray; temp: BOOLEAN; loc: SynLocation.T) : ObValue.Val RAISES {ObValue.Error, ObValue.Exception} = VAR wr1: Wr.T; text1: TEXT; char1: CHAR; int1: INTEGER := 0; fileSys1: ObValue.ValFileSystem; BEGIN TRY CASE NARROW(opCode, WrOpCode).code OF | WrCode.Failure => RETURN wrFailureException; | WrCode.New => wr1 := TextWr.New(); RETURN NEW(ValWr, what:="<a writer>", tag:="Writer", picklable:=FALSE, wr:=wr1); | WrCode.Stdout => RETURN NEW(ValWr, what:="<stdout writer>", tag:="Writer", picklable:=FALSE, wr:=Stdio.stdout); | WrCode.Stderr => RETURN NEW(ValWr, what:="<stderr writer>", tag:="Writer", picklable:=FALSE, wr:=Stdio.stderr); | WrCode.Open => TYPECASE args[1] OF | ObValue.ValFileSystem(node) => fileSys1:=node; ELSE ObValue.BadArgType(1, "file system", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(2, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; wr1 := fileSys1.remote.OpenWrite(text1); RETURN NEW(ValWr, what:="<'" & text1 & "' writer>", tag:="Writer", picklable:=FALSE, wr:=wr1); | WrCode.OpenAppend => TYPECASE args[1] OF | ObValue.ValFileSystem(node) => fileSys1:=node; ELSE ObValue.BadArgType(1, "file system", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(2, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; wr1 := fileSys1.remote.OpenAppend(text1); RETURN NEW(ValWr, what:="<'" & text1 & "' writer>", tag:="Writer", picklable:=FALSE, wr:=wr1); | WrCode.ToText => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE wr1 OF | TextWr.T(wr) => RETURN ObValue.NewText(TextWr.ToText(wr)); ELSE ObValue.BadArgVal(1, "locally produced by wr_new", self.name, opCode.name, loc);<*ASSERT FALSE*> END; | WrCode.PutChar => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValChar(node) => char1 := node.char; ELSE ObValue.BadArgType(2, "char", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Closed(wr1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc);<*ASSERT FALSE*> END; Wr.PutChar(wr1, char1); RETURN ObValue.valOk; | WrCode.PutText => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(2, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Closed(wr1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc);<*ASSERT FALSE*> END; Wr.PutText(wr1, text1); RETURN ObValue.valOk; | WrCode.Flush => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Closed(wr1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc);<*ASSERT FALSE*> END; Wr.Flush(wr1); RETURN ObValue.valOk; | WrCode.Index => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Closed(wr1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc);<*ASSERT FALSE*> END; RETURN NEW(ObValue.ValInt, int:=Wr.Index(wr1), temp:=temp); | WrCode.Length => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Closed(wr1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc);<*ASSERT FALSE*> END; RETURN NEW(ObValue.ValInt, int:=Wr.Length(wr1), temp:=temp); | WrCode.Seek => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Closed(wr1) THEN ObValue.BadArgVal(1, "non-closed", self.name, opCode.name, loc);<*ASSERT FALSE*> END; IF NOT Wr.Seekable(wr1) THEN ObValue.BadArgVal(1, "seekable", self.name, opCode.name, loc);<*ASSERT FALSE*> END; IF int1<0 THEN ObValue.BadArgVal(2, "non-negative", self.name, opCode.name, loc);<*ASSERT FALSE*> END; Wr.Seek(wr1, int1); RETURN ObValue.valOk; | WrCode.Close => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; Wr.Close(wr1); RETURN ObValue.valOk; | WrCode.Buffered => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Buffered(wr1) THEN RETURN true ELSE RETURN false END; | WrCode.Seekable => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Seekable(wr1) THEN RETURN true ELSE RETURN false END; | WrCode.Closed => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Wr.Closed(wr1) THEN RETURN true ELSE RETURN false END; ELSE ObValue.BadOp(self.name, opCode.name, loc);<*ASSERT FALSE*> END; EXCEPT | Wr.Failure, ObValue.ServerError => ObValue.RaiseException(wrFailureException, self.name & "_" & opCode.name, loc); <*ASSERT FALSE*> | Thread.Alerted => ObValue.RaiseException(ObValue.threadAlerted, self.name&"_"&opCode.name, loc); <*ASSERT FALSE*> | NetObj.Error(atoms) => ObValue.RaiseNetException(self.name&"_"&opCode.name, atoms, loc); <*ASSERT FALSE*> END; END EvalWr;
lex
package ============
TYPE LexCode = {Failure, Scan, Skip, Match, Bool, Int, Real}; LexOpCode = ObLib.OpCode OBJECT code: LexCode; END; PackageLex = ObLib.T OBJECT OVERRIDES Eval:=EvalLex; END; VAR lexFailureException: ObValue.ValException; PROCEDURE============NewLexOC (name: TEXT; arity: INTEGER; code: LexCode) : LexOpCode = BEGIN RETURN NEW(LexOpCode, name:=name, arity:=arity, code:=code); END NewLexOC; PROCEDURESetupLex () = TYPE OpCodes = ARRAY OF ObLib.OpCode; VAR opCodes: REF OpCodes; BEGIN opCodes := NEW(REF OpCodes, NUMBER(LexCode)); opCodes^ := OpCodes{ NewLexOC("failure", -1, LexCode.Failure), NewLexOC("scan", 2, LexCode.Scan), NewLexOC("skip", 2, LexCode.Skip), NewLexOC("match", 2, LexCode.Match), NewLexOC("bool", 1, LexCode.Bool), NewLexOC("int", 1, LexCode.Int), NewLexOC("real", 1, LexCode.Real) }; ObLib.Register( NEW(PackageLex, name:="lex", opCodes:=opCodes)); lexFailureException := NEW(ObValue.ValException, name:="lex_failure"); END SetupLex; PROCEDUREEvalLex (self: PackageLex; opCode: ObLib.OpCode; <*UNUSED*>arity: ObLib.OpArity; READONLY args: ObValue.ArgArray; temp: BOOLEAN; loc: SynLocation.T) : ObValue.Val RAISES {ObValue.Error, ObValue.Exception} = VAR text1: TEXT; rd1: Rd.T; BEGIN TRY CASE NARROW(opCode, LexOpCode).code OF | LexCode.Failure => RETURN lexFailureException; | LexCode.Scan => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(2, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN ObValue.NewText(Lex.Scan(rd1, CharSet(text1))); | LexCode.Skip => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(2, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; Lex.Skip(rd1, CharSet(text1)); RETURN ObValue.valOk; | LexCode.Match => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(2, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; Lex.Match(rd1, text1); RETURN ObValue.valOk; | LexCode.Bool => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF Lex.Bool(rd1) THEN RETURN true ELSE RETURN false END; | LexCode.Int => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN NEW(ObValue.ValInt, int:=Lex.Int(rd1, 10), temp:=temp); | LexCode.Real => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN NEW(ObValue.ValReal, real:=Lex.LongReal(rd1), temp:=temp); ELSE ObValue.BadOp(self.name, opCode.name, loc);<*ASSERT FALSE*> END; EXCEPT | Lex.Error, FloatMode.Trap => ObValue.RaiseException(lexFailureException, self.name & "_" & opCode.name, loc); <*ASSERT FALSE*> | Rd.Failure => ObValue.RaiseException(rdFailureException, self.name & "_" & opCode.name, loc); <*ASSERT FALSE*> | Thread.Alerted => ObValue.RaiseException(ObValue.threadAlerted, self.name&"_"&opCode.name, loc); <*ASSERT FALSE*> END; END EvalLex; PROCEDURECharSet (text: TEXT): SET OF CHAR = VAR s: SET OF CHAR; BEGIN s := SET OF CHAR{}; FOR i:=0 TO Text.Length(text)-1 DO s := s + SET OF CHAR{Text.GetChar(text,i)}; END; RETURN s; END CharSet;
fmt
package ============
TYPE FmtCode = {PadLft, PadRht, Bool, Int, Real}; FmtOpCode = ObLib.OpCode OBJECT code: FmtCode; END; PackageFmt = ObLib.T OBJECT OVERRIDES Eval:=EvalFmt; END; PROCEDURE============NewFmtOC (name: TEXT; arity: INTEGER; code: FmtCode) : FmtOpCode = BEGIN RETURN NEW(FmtOpCode, name:=name, arity:=arity, code:=code); END NewFmtOC; PROCEDURESetupFmt () = TYPE OpCodes = ARRAY OF ObLib.OpCode; VAR opCodes: REF OpCodes; BEGIN opCodes := NEW(REF OpCodes, NUMBER(FmtCode)); opCodes^ := OpCodes{ NewFmtOC("padLft", 2, FmtCode.PadLft), NewFmtOC("padRht", 2, FmtCode.PadRht), NewFmtOC("bool", 1, FmtCode.Bool), NewFmtOC("int", 1, FmtCode.Int), NewFmtOC("real", 1, FmtCode.Real) }; ObLib.Register( NEW(PackageFmt, name:="fmt", opCodes:=opCodes)); END SetupFmt; PROCEDUREEvalFmt (self: PackageFmt; opCode: ObLib.OpCode; <*UNUSED*>arity: ObLib.OpArity; READONLY args: ObValue.ArgArray; <*UNUSED*>temp: BOOLEAN; loc: SynLocation.T) : ObValue.Val RAISES {ObValue.Error} = VAR text1: TEXT; bool1: BOOLEAN; int1: INTEGER := 0; real1: LONGREAL; BEGIN CASE NARROW(opCode, FmtOpCode).code OF | FmtCode.PadLft => TYPECASE args[1] OF | ObValue.ValText(node) => text1 := node.text; ELSE ObValue.BadArgType(1, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN ObValue.NewText(Fmt.Pad(text1, int1, ' ', Fmt.Align.Left)); | FmtCode.PadRht => TYPECASE args[1] OF | ObValue.ValText(node) => text1 := node.text; ELSE ObValue.BadArgType(1, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN ObValue.NewText(Fmt.Pad(text1, int1, ' ', Fmt.Align.Right)); | FmtCode.Bool => TYPECASE args[1] OF | ObValue.ValBool(node) => bool1 := node.bool; ELSE ObValue.BadArgType(1, "bool", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF bool1 THEN RETURN ObValue.NewText("true"); ELSE RETURN ObValue.NewText("false"); END; | FmtCode.Int => TYPECASE args[1] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(1, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN ObValue.NewText(Fmt.Int(int1)); | FmtCode.Real => TYPECASE args[1] OF | ObValue.ValReal(node) => real1 := node.real; ELSE ObValue.BadArgType(1, "real", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN ObValue.NewText(Fmt.LongReal(real1, literal:=TRUE)); ELSE ObValue.BadOp(self.name, opCode.name, loc);<*ASSERT FALSE*> END; END EvalFmt;
word
package ============
TYPE WordCode = {Not, And, Or, Xor, Shift, Rotate}; WordOpCode = ObLib.OpCode OBJECT code: WordCode; END; PackageWord = ObLib.T OBJECT OVERRIDES Eval:=EvalWord; END; PROCEDURE============NewWordOC (name: TEXT; arity: INTEGER; code: WordCode) : WordOpCode = BEGIN RETURN NEW(WordOpCode, name:=name, arity:=arity, code:=code); END NewWordOC; PROCEDURESetupWord () = TYPE OpCodes = ARRAY OF ObLib.OpCode; VAR opCodes: REF OpCodes; BEGIN opCodes := NEW(REF OpCodes, NUMBER(WordCode)); opCodes^ := OpCodes{ NewWordOC("bitnot", 1, WordCode.Not), NewWordOC("bitand", 2, WordCode.And), NewWordOC("bitor", 2, WordCode.Or), NewWordOC("bitxor", 2, WordCode.Xor), NewWordOC("bitshift", 2, WordCode.Shift), NewWordOC("bitrotate", 2, WordCode.Rotate) }; ObLib.Register( NEW(PackageWord, name:="word", opCodes:=opCodes)); END SetupWord; PROCEDUREEvalWord (self: PackageWord; opCode: ObLib.OpCode; <*UNUSED*>arity: ObLib.OpArity; READONLY args: ObValue.ArgArray; <*UNUSED*>temp: BOOLEAN; loc: SynLocation.T) : ObValue.Val RAISES {ObValue.Error} = VAR int1, int2: INTEGER := 0; BEGIN CASE NARROW(opCode, WordOpCode).code OF | WordCode.Not => TYPECASE args[1] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(1, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN Obliq.NewInt(Word.Not (int1)); | WordCode.And => TYPECASE args[1] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(1, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValInt(node) => int2 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN Obliq.NewInt(Word.And (int1, int2)); | WordCode.Or => TYPECASE args[1] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(1, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValInt(node) => int2 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN Obliq.NewInt(Word.Or (int1, int2)); | WordCode.Xor => TYPECASE args[1] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(1, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValInt(node) => int2 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN Obliq.NewInt(Word.Xor (int1, int2)); | WordCode.Shift => TYPECASE args[1] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(1, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValInt(node) => int2 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN Obliq.NewInt(Word.Shift (int1, int2)); | WordCode.Rotate => TYPECASE args[1] OF | ObValue.ValInt(node) => int1 := node.int; ELSE ObValue.BadArgType(1, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[2] OF | ObValue.ValInt(node) => int2 := node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*>END; RETURN Obliq.NewInt(Word.Rotate (int1, int2)); ELSE ObValue.BadOp(self.name, opCode.name, loc);<*ASSERT FALSE*> END; END EvalWord;
pickle
package ============
CONST CurrentPickleVersion = 2; TYPE PickleVersion = BRANDED "ObliqPickleVersion" OBJECT version: INTEGER END; TYPE PickleCode = {Failure, Write, Read}; PickleOpCode = ObLib.OpCode OBJECT code: PickleCode; END; PackagePickle = ObLib.T OBJECT OVERRIDES Eval:=EvalPickle; END; VAR pickleFailureException: ObValue.ValException; PROCEDURE============NewPickleOC (name: TEXT; arity: INTEGER; code: PickleCode) : PickleOpCode = BEGIN RETURN NEW(PickleOpCode, name:=name, arity:=arity, code:=code); END NewPickleOC; PROCEDURESetupPickle () = TYPE OpCodes = ARRAY OF ObLib.OpCode; VAR opCodes: REF OpCodes; BEGIN opCodes := NEW(REF OpCodes, NUMBER(PickleCode)); opCodes^ := OpCodes{ NewPickleOC("failure", -1, PickleCode.Failure), NewPickleOC("write", 2, PickleCode.Write), NewPickleOC("read", 1, PickleCode.Read) }; ObLib.Register( NEW(PackagePickle, name:="pickle", opCodes:=opCodes)); pickleFailureException := NEW(ObValue.ValException, name:="pickle_failure"); END SetupPickle; PROCEDUREEvalPickle (self: PackagePickle; opCode: ObLib.OpCode; <*UNUSED*>arity: ObLib.OpArity; READONLY args: ObValue.ArgArray; <*UNUSED*>temp: BOOLEAN; loc: SynLocation.T) : ObValue.Val RAISES {ObValue.Error, ObValue.Exception} = VAR wr1: Wr.T; rd1: Rd.T; BEGIN TRY CASE NARROW(opCode, PickleOpCode).code OF | PickleCode.Failure => RETURN pickleFailureException; | PickleCode.Write => TYPECASE args[1] OF | ValWr(node) => wr1 := node.wr; ELSE ObValue.BadArgType(1, "wr", self.name, opCode.name, loc); <*ASSERT FALSE*>END; Pickle.Write(wr1, NEW(PickleVersion, version:=CurrentPickleVersion)); Pickle.Write(wr1, ObValue.CopyValToLocal(args[2], ObValue.NewTbl(), loc)); RETURN ObValue.valOk; | PickleCode.Read => TYPECASE args[1] OF | ValRd(node) => rd1 := node.rd; ELSE ObValue.BadArgType(1, "rd", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE Pickle.Read(rd1) OF | PickleVersion(p) => IF p.version # CurrentPickleVersion THEN RAISE Pickle.Error(""); END; ELSE RAISE Pickle.Error(""); END; RETURN ObValue.CopyLocalToVal(Pickle.Read(rd1), ObValue.NewTbl(), loc); ELSE ObValue.BadOp(self.name, opCode.name, loc);<*ASSERT FALSE*> END; EXCEPT | Pickle.Error => ObValue.RaiseException(pickleFailureException, opCode.name, loc); <*ASSERT FALSE*> | Wr.Failure => ObValue.RaiseException(wrFailureException, opCode.name, loc); <*ASSERT FALSE*> | Rd.Failure => ObValue.RaiseException(rdFailureException, opCode.name, loc); <*ASSERT FALSE*> | Rd.EndOfFile => ObValue.RaiseException(rdEofFailureException, opCode.name, loc); <*ASSERT FALSE*> | Thread.Alerted => ObValue.RaiseException(ObValue.threadAlerted, self.name&"_"&opCode.name, loc); <*ASSERT FALSE*> | NetObj.Error(atoms) => ObValue.RaiseNetException(self.name&"_"&opCode.name, atoms, loc); <*ASSERT FALSE*> | SharedObj.Error(atoms) => ObValue.RaiseSharedException(self.name&"_"&opCode.name, atoms, loc); <*ASSERT FALSE*> END; END EvalPickle;
process
package ============
TYPE ProcCode = {New, In, Out, Err, Complete, Filter}; ProcOpCode = ObLib.OpCode OBJECT code: ProcCode; END; PackageProc = ObLib.T OBJECT OVERRIDES Eval:=EvalProc; END; PROCEDURE============IsProc (self: ValProc; other: ObValue.ValAnything): BOOLEAN = BEGIN TYPECASE other OF ValProc(oth)=> RETURN self.proc = oth.proc; ELSE RETURN FALSE END; END IsProc; PROCEDURECopyProc (<*UNUSED*>self: ObValue.ValAnything; <*UNUSED*>tbl: ObValue.Tbl; loc: SynLocation.T): ObValue.ValAnything RAISES {ObValue.Error} = BEGIN ObValue.RaiseError("Cannot copy processes", loc);<*ASSERT FALSE*> END CopyProc; PROCEDURENewProcOC (name: TEXT; arity: INTEGER; code: ProcCode) : ProcOpCode = BEGIN RETURN NEW(ProcOpCode, name:=name, arity:=arity, code:=code); END NewProcOC; PROCEDURESetupProc () = TYPE OpCodes = ARRAY OF ObLib.OpCode; VAR opCodes: REF OpCodes; BEGIN opCodes := NEW(REF OpCodes, NUMBER(ProcCode)); opCodes^ := OpCodes{ NewProcOC("new", 3, ProcCode.New), NewProcOC("in", 1, ProcCode.In), NewProcOC("out", 1, ProcCode.Out), NewProcOC("err", 1, ProcCode.Err), NewProcOC("complete", 1, ProcCode.Complete), NewProcOC("filter", 3, ProcCode.Filter)}; ObLib.Register( NEW(PackageProc, name:="process", opCodes:=opCodes)); ObValue.InhibitTransmission(TYPECODE(ValProc), "processes cannot be transmitted/duplicated"); END SetupProc; PROCEDUREEvalProc (self: PackageProc; opCode: ObLib.OpCode; <*UNUSED*>arity: ObLib.OpArity; READONLY args: ObValue.ArgArray; temp: BOOLEAN; loc: SynLocation.T) : ObValue.Val RAISES {ObValue.Error, ObValue.Exception} = TYPE Texts = REF ARRAY OF TEXT; VAR val: ObValue.Val; text1: TEXT; size, int: INTEGER; proc: Process.T; proc1: ValProc; texts: Texts; stdinR, stdinW, stdoutR, stdoutW, stderrR, stderrW: Pipe.T; stdinWr: FileWr.T; stdoutRd, stderrRd: FileRd.T; bool1: BOOLEAN; array1: REF ObValue.Vals; processor1: ObValue.ValProcessor; BEGIN TRY CASE NARROW(opCode, ProcOpCode).code OF | ProcCode.New => TYPECASE args[1] OF | ObValue.ValProcessor(node) => processor1:=node; ELSE ObValue.BadArgType(1, "processor", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF processor1 # ObValue.localProcessor THEN ObValue.BadArgVal(1, "the local processor", self.name, opCode.name, loc); <*ASSERT FALSE*> END; TYPECASE args[2] OF | ObValue.ValArray(node) => array1:=node.remote.Obtain(); ELSE ObValue.BadArgType(2, "array", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[3] OF | ObValue.ValBool(node) => bool1:=node.bool; ELSE ObValue.BadArgType(3, "bool", self.name, opCode.name, loc); <*ASSERT FALSE*>END; size := NUMBER(array1^); IF size=0 THEN ObValue.BadArgVal(2, "non-empty", self.name, opCode.name, loc);<*ASSERT FALSE*> END; texts := NEW(Texts, size); FOR i := 0 TO size-1 DO TYPECASE array1^[i] OF | ObValue.ValText(node) => texts^[i] := node.text; ELSE ObValue.BadArgType(2, "array(text)", self.name, opCode.name,loc); <*ASSERT FALSE*> END; END; Pipe.Open((*out*)stdinR, (*out*)stdinW); Pipe.Open((*out*)stdoutR, (*out*)stdoutW); IF bool1 THEN stderrR := stdoutR; stderrW := stdoutW; ELSE Pipe.Open((*out*)stderrR, (*out*)stderrW); END; proc := Process.Create(texts^[0], SUBARRAY(texts^, 1, NUMBER(texts^)-1), NIL, NIL, stdinR, stdoutW, stderrW); stdinR.close(); stdoutW.close(); IF NOT bool1 THEN stderrW.close(); END; stdinWr := NEW(FileWr.T).init(stdinW); stdoutRd := NEW(FileRd.T).init(stdoutR); IF bool1 THEN stderrRd := stdoutRd; ELSE stderrRd := NEW(FileRd.T).init(stderrR); END; RETURN NEW(ValProc, what:="<a process>", tag:="Process", picklable:=FALSE, proc:=proc, in := NEW(ValWr, what:="<a process stdin writer>", tag:="Writer", picklable:=FALSE, wr:=stdinWr), out := NEW(ValRd, what:="<a process stdout reader>", tag:="Reader",picklable:=FALSE, rd := stdoutRd), err := NEW(ValRd, what:="<a process stderr reader>", tag:="Reader", picklable:=FALSE, rd := stderrRd)); | ProcCode.In => TYPECASE args[1] OF | ValProc(node) => proc1 := node; ELSE ObValue.BadArgType(1, "process", self.name, opCode.name, loc); <*ASSERT FALSE*> END; RETURN proc1.in; | ProcCode.Out => TYPECASE args[1] OF | ValProc(node) => proc1 := node; ELSE ObValue.BadArgType(1, "process", self.name, opCode.name, loc); <*ASSERT FALSE*> END; RETURN proc1.out; | ProcCode.Err => TYPECASE args[1] OF | ValProc(node) => proc1 := node; ELSE ObValue.BadArgType(1, "process", self.name, opCode.name, loc); <*ASSERT FALSE*> END; RETURN proc1.err; | ProcCode.Complete => TYPECASE args[1] OF | ValProc(node) => proc1 := node; ELSE ObValue.BadArgType(1, "process", self.name, opCode.name, loc); <*ASSERT FALSE*> END; int := Process.Wait(proc1.proc); Wr.Close(proc1.in.wr); Rd.Close(proc1.out.rd); Rd.Close(proc1.err.rd); RETURN NEW(ObValue.ValInt, int := int, temp:=temp); | ProcCode.Filter => TYPECASE args[1] OF | ObValue.ValProcessor(node) => processor1:=node; ELSE ObValue.BadArgType(1, "processor", self.name, opCode.name, loc); <*ASSERT FALSE*>END; IF processor1 # ObValue.localProcessor THEN ObValue.BadArgVal(1, "the local processor", self.name, opCode.name, loc);<*ASSERT FALSE*> END; TYPECASE args[2] OF | ObValue.ValArray(node) => array1:=node.remote.Obtain(); ELSE ObValue.BadArgType(2, "array", self.name, opCode.name, loc); <*ASSERT FALSE*>END; TYPECASE args[3] OF | ObValue.ValText(node) => text1:=node.text; ELSE ObValue.BadArgType(3, "text", self.name, opCode.name, loc); <*ASSERT FALSE*>END; size := NUMBER(array1^); IF size=0 THEN ObValue.BadArgVal(2, "non-empty", self.name, opCode.name, loc);<*ASSERT FALSE*> END; texts := NEW(Texts, size); FOR i := 0 TO size-1 DO TYPECASE array1^[i] OF | ObValue.ValText(node) => texts^[i] := node.text; ELSE ObValue.BadArgType(2, "array(text)", self.name, opCode.name, loc);<*ASSERT FALSE*> END; END; Pipe.Open((*out*)stdinR, (*out*)stdinW); Pipe.Open((*out*)stdoutR, (*out*)stdoutW); proc := Process.Create(texts^[0], SUBARRAY(texts^, 1, NUMBER(texts^)-1), NIL, NIL, stdinR, stdoutW, stdoutW); stdinR.close(); stdoutW.close(); stdinWr := NEW(FileWr.T).init(stdinW); stdoutRd := NEW(FileRd.T).init(stdoutR); Wr.PutText(stdinWr, text1); Wr.Close(stdinWr); val := ObValue.NewText(Rd.GetText(stdoutRd, LAST(CARDINAL))); Rd.Close(stdoutRd); EVAL Process.Wait(proc); RETURN val; (* -- LocalPipe | ProcCode.Pipe => TYPECASE args[1] OF | ObValue.ValBool(node) => bool1:=node.bool; ELSE ObValue.BadArgType(1, "bool", self.name, opCode.name, loc); END; rd1 := NEW(LocalPipe.Reaader); wr1 := NEW(LocalPipe.Writer); LocalPipe.Init(rd1, wr1, NOT bool1); RETURN ObValue.NewObject( NEW(ObValue.ObjFieldValue, label:="r", val:=NEW(ValRd, what:="<a pipe reader>", tag:="Reader", picklable:=FALSE, rd:=rd1), rest:=NEW(ObValue.ObjFieldValue( label:="w", val:=NEW(ValWr, what:="<a pipe writer>", tag:="Writer", picklable:=FALSE, wr:=wr1), rest:=NIL))); ); *) ELSE ObValue.BadOp(self.name, opCode.name, loc);<*ASSERT FALSE*> END; EXCEPT | Rd.Failure, Wr.Failure, Thread.Alerted, OSError.E => ObValue.RaiseError(self.name&"_"&opCode.name, loc);<*ASSERT FALSE*> | NetObj.Error(atoms) => ObValue.RaiseNetException( self.name&"_"&opCode.name, atoms, loc);<*ASSERT FALSE*> END; END EvalProc;
random
package ============
TYPE RandomCode = {Int, Real}; RandomOpCode = ObLib.OpCode OBJECT code: RandomCode; END; PackageRandom = ObLib.T OBJECT OVERRIDES Eval:=EvalRandom; END; PROCEDURENewRandomOC (name: TEXT; arity: INTEGER; code: RandomCode) : RandomOpCode = BEGIN RETURN NEW(RandomOpCode, name:=name, arity:=arity, code:=code); END NewRandomOC; PROCEDURESetupRandom () = TYPE OpCodes = ARRAY OF ObLib.OpCode; VAR opCodes: REF OpCodes; BEGIN opCodes := NEW(REF OpCodes, NUMBER(RandomCode)); opCodes^ := OpCodes{ NewRandomOC("int", 2, RandomCode.Int), NewRandomOC("real", 2, RandomCode.Real) }; ObLib.Register( NEW(PackageRandom, name:="random", opCodes:=opCodes)); END SetupRandom; PROCEDUREEvalRandom (self: PackageRandom; opCode: ObLib.OpCode; <*UNUSED*>arity: ObLib.OpArity; READONLY args: ObValue.ArgArray; <*UNUSED*>temp: BOOLEAN; loc: SynLocation.T) : ObValue.Val RAISES {ObValue.Error} = VAR real1, real2: LONGREAL; int1, int2: INTEGER := 0; BEGIN CASE NARROW(opCode, RandomOpCode).code OF | RandomCode.Int => TYPECASE args[1] OF | ObValue.ValInt(node) => int1:=node.int; ELSE ObValue.BadArgType(1, "int", self.name, opCode.name, loc); <*ASSERT FALSE*> END; TYPECASE args[2] OF | ObValue.ValInt(node) => int2:=node.int; ELSE ObValue.BadArgType(2, "int", self.name, opCode.name, loc); <*ASSERT FALSE*> END; LOCK randomMu DO RETURN Obliq.NewInt(random.integer(int1,int2)) END; | RandomCode.Real => TYPECASE args[1] OF | ObValue.ValReal(node) => real1:=node.real; ELSE ObValue.BadArgType(1, "real", self.name, opCode.name, loc); <*ASSERT FALSE*> END; TYPECASE args[2] OF | ObValue.ValReal(node) => real2:=node.real; ELSE ObValue.BadArgType(2, "real", self.name, opCode.name, loc); <*ASSERT FALSE*> END; LOCK randomMu DO RETURN Obliq.NewReal(random.longreal(real1,real2)) END; ELSE ObValue.BadOp(self.name, opCode.name, loc);<*ASSERT FALSE*> END; END EvalRandom; VAR randomMu := NEW(MUTEX); random := NEW(Random.Default).init(); BEGIN END ObLibM3.