-- Juno2TopImpl.mesa -- August 30, 1983 12:45 pm -- Last Edited by: Gnelson, December 10, 1983 4:41 pm DIRECTORY Juno2Top, ParseWindow, ViewerTools, IO, Parser, ParserGen, Atom, Lexer, Rope, Process, JunoExec, Lisp, PrettyPrint, JunoBind, JunoSolver, JunoToCedar, ParseTable, JunoSyntax; Juno2TopImpl: PROGRAM IMPORTS ParseWindow, ViewerTools, IO, Parser, Lexer, JunoToCedar, Rope, Process, JunoExec, Lisp, JunoBind, Atom, ParseTable, JunoSyntax EXPORTS Juno2Top = {OPEN Lisp, JB: JunoBind, JS: JunoSyntax; ROPE: TYPE = Rope.ROPE; defs: ParseWindow.Handle _ ParseWindow.NewHandle [ViewerTools.MakeNewTextViewer[[file: "active.juno2", name: "active.juno2"]]]; -- because the parser generator is not very smart about unparsing, we need to adjust -- the unparsing types of a few operators for which convention dictates a non-standard -- format: FixUpUnparserTypes: PROC[] = { Fix: PROC[a: ATOM, n: INT] = { p: ParseTable.Properties = ParseTable.Search[defs.ph.table, a, NIL]; p.unparserType _ n}; Fix[JS.comma, 7]; Fix[JS.semicolon, 7]; Fix[JS.colon, 7]; Fix[JS.leftpren, 6]; Fix[JS.leftbracket, 6]}; Parse2: PUBLIC PROC [] = {ParseWindow.ParseViewer[defs]}; al: PUBLIC JB.Alist _ JB.EmptyBinding[]; Create: PUBLIC PROC[l: LIST OF REF] = {al _ JB.NewBind[al, Atom.MakeAtom[NARROW[l.first]], l.rest.first]}; -- defs is the window of definitions of procedures, predicates, and functions. in: IO.STREAM; out: IO.STREAM; -- These two streams will be used for the interpreter's read-eval-print loop Print2: PUBLIC PROC[l: LIST OF REF] = {WHILE l # NIL DO Print3[l.first]; l _ l.rest ENDLOOP}; Print3: PROC[r: REF] = { WITH r SELECT FROM rr: REF REAL => IO.Put[out, IO.real[rr^]]; rt: ROPE => IO.Put[out, IO.rope[rt]]; ri: REF INT => IO.Put[out, IO.int[ri^]]; rt: REF TEXT => IO.Put[out, IO.text[rt]]; a: ATOM => IO.Put[out, IO.atom[a]]; rc: REF CHAR => IO.Put[out, IO.char[rc^]]; rb: REF BOOL => IO.Put[out, IO.bool[rb^]] ENDCASE => ERROR}; interpreterParser: Parser.Handle _ Parser.NewHandle[]; -- this parser will be hooked up to the input stream in; it will -- parse the same language as the parser within defs. ReadEvalPrint: PUBLIC PROC[prompt: ROPE, env: JB.Alist, defs: REF] RETURNS [al: JB.Alist] = {P: IO.BreakProc -- [char: CHAR] RETURNS [CharClass], CharClass = {break, sepr, other} = TRUSTED {IF char = IO.CR THEN RETURN [break] ELSE RETURN [other]}; r: ROPE; al _ env; DO ENABLE {ABORTED => LOOP}; IO.Put[out, IO.rope["\n"], IO.rope[prompt]]; r _ IO.GetToken[in, P]; -- read a line from the interpreter window [] _ IO.GetToken[in, P]; -- read and ignore the CR that terminated r interpreterParser.in.in _ IO.RIS[Rope.Concat[r, " "]]; -- convert it to a stream and hook it to the parser interpreterParser.in.eof _ FALSE; interpreterParser.in.error _ NIL; Lexer.Lex[interpreterParser.in]; IF interpreterParser.in.eof THEN LOOP; Parser.Parse[interpreterParser]; IF interpreterParser.error # NIL OR ~ interpreterParser.eof THEN {IO.Put[out, IO.rope["Syntax error"]]; LOOP}; IF interpreterParser.result = $Debug THEN SIGNAL Debug; interpreterParser.result _ CONS[interpreterParser.result, NIL]; al _ JunoExec.Exec[Car[interpreterParser.result], al, defs]; ENDLOOP}; Debug: SIGNAL = CODE; Foo: PROC[] = {bar: JB.Alist _ ReadEvalPrint["-> ", al, defs];}; GetProc: PROC[moduleName: ROPE, procName: ROPE] RETURNS [p: PROC ANY RETURNS ANY] = { success: BOOL; [success, p] _ JunoToCedar.GetProc[[moduleName, procName]]; IF NOT success THEN ERROR}; [in, out] _ IO.CreateViewerStreams["Juno Interpreter"]; defs.grammerfilename _ "juno2.grammar"; ParseWindow.GenerateParser[defs]; FixUpUnparserTypes[]; Parse2[]; -- The above commands generate the parser. Next, extract the appropriate pieces -- and hook them up into a parser for the interpreter window. {lexer: Lexer.Handle _ Lexer.NewHandle[]; lexer.type _ defs.ph.in.type; lexer.opList _ defs.ph.in.opList; interpreterParser.in _ lexer; interpreterParser.table _ defs.ph.table}; Create[LIST[Rope.FromRefText["Create"], NEW[PROC ANY RETURNS ANY _ Create]]]; Create[LIST[Rope.FromRefText["GetProc"], NEW[PROC ANY RETURNS ANY _ GetProc]]]; [] _ JunoExec.Exec[$Init, al, defs]; Process.Detach[FORK Foo[]]; }.