diff options
Diffstat (limited to 'src/interp/cparse.boot')
-rw-r--r-- | src/interp/cparse.boot | 988 |
1 files changed, 988 insertions, 0 deletions
diff --git a/src/interp/cparse.boot b/src/interp/cparse.boot new file mode 100644 index 00000000..c49ee250 --- /dev/null +++ b/src/interp/cparse.boot @@ -0,0 +1,988 @@ +-- Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd. +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions are +-- met: +-- +-- - Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- +-- - Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in +-- the documentation and/or other materials provided with the +-- distribution. +-- +-- - Neither the name of The Numerical ALgorithms Group Ltd. nor the +-- names of its contributors may be used to endorse or promote products +-- derived from this software without specific prior written permission. +-- +-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +-- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +-- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +-- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +-- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +-- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import '"ptrees" + +)package "BOOT" + +-- npTerm introduced between npRemainder and npSum +-- rhs of assignment changed from npStatement to npGives + +npParse stream == + $inputStream:local := stream + $stack:local :=nil + $stok:local:=nil + $ttok:local:=nil + npFirstTok() + found:=CATCH("TRAPPOINT",npItem()) + if found="TRAPPED" + then + ncSoftError(tokPosn $stok,'S2CY0006, []) + pfWrong(pfDocument '"top level syntax error" ,pfListOf nil) + else if not null $inputStream + then + ncSoftError(tokPosn $stok,'S2CY0002,[]) + pfWrong(pfDocument ['"input stream not exhausted"],pfListOf []) + else if null $stack + then + ncSoftError(tokPosn $stok,'S2CY0009, []) + pfWrong(pfDocument ['"stack empty"],pfListOf []) + else + CAR $stack + +npItem()== + npQualDef() => + npEqKey "SEMICOLON" => + [a,b]:=npItem1 npPop1 () + c:=pfEnSequence b + a => npPush c + npPush pfNovalue c + npPush pfEnSequence npPop1 () + false + +npItem1 c== + npQualDef() => + npEqKey "SEMICOLON" => + [a,b]:=npItem1 npPop1 () + [a,append(c,b)] + [true,append (c,npPop1())] + [false,c] + +npFirstTok()== + $stok:= + if null $inputStream + then tokConstruct("ERROR","NOMORE",tokPosn $stok) + else CAR $inputStream + $ttok:=tokPart $stok + +npNext() == + $inputStream := CDR($inputStream) + npFirstTok() + +npState()==cons($inputStream,$stack) + +npRestore(x)== + $inputStream:=CAR x + npFirstTok() + $stack:=CDR x + true + +npPush x==$stack:=CONS(x,$stack) + +npPushId()== + a:=GETL($ttok,'INFGENERIC) + $ttok:= if a then a else $ttok + $stack:=CONS(tokConstruct("id",$ttok,tokPosn $stok),$stack) + npNext() + +npPop1()== + a:=CAR $stack + $stack:=CDR $stack + a + +npPop2()== + a:=CADR $stack + RPLACD($stack,CDDR $stack) + a + +npPop3()== + a:=CADDR $stack + RPLACD(CDR $stack,CDDDR $stack) + a + +npParenthesized f== + npParenthesize("(",")",f) or + npParenthesize("(|","|)",f) + +npParenthesize (open,close,f)== + a:=$stok + npEqKey open => + APPLY(f,nil) and (npEqKey close or npMissingMate(close,a))=> true + npEqKey close => npPush [] + npMissingMate(close,a) + false + +npEnclosed(open,close,fn,f)== + a:=$stok + npEqKey open => + npEqKey close => npPush FUNCALL(fn,a,pfTuple pfListOf []) + APPLY(f,nil) and (npEqKey close or npMissingMate(close,a))=> + npPush FUNCALL (fn,a,pfEnSequence npPop1()) + false + false + +npParened f == + npEnclosed("(",")",function pfParen,f) or + npEnclosed("(|","|)",function pfParen,f) + +npBracked f == + npEnclosed("[","]",function pfBracket,f) or + npEnclosed("[|","|]",function pfBracketBar,f) + +npBraced f == + npEnclosed("{","}",function pfBrace,f) or + npEnclosed("{|","|}",function pfBraceBar,f) + +npAngleBared f == + npEnclosed("<|","|>",function pfHide,f) + +npBracketed f== + npParened f or npBracked f or npBraced f or npAngleBared f + +npPileBracketed f== + if npEqKey "SETTAB" + then if npEqKey "BACKTAB" + then npPush pfNothing() -- never happens + else if APPLY(f,nil) and (npEqKey "BACKTAB" or npMissing "backtab") + then npPush pfPile npPop1() + else false + else false + +npListofFun(f,h,g)== + if APPLY(f,nil) + then + if APPLY(h,nil) and (APPLY(f,nil) or npTrap()) + then + a:=$stack + $stack:=nil + while APPLY(h,nil) and (APPLY(f,nil) or npTrap()) repeat 0 + $stack:=cons(NREVERSE $stack,a) + npPush FUNCALL(g, [npPop3(),npPop2(),:npPop1()]) + else + true + else false + +npList(f,str1,g)== -- always produces a list, g is applied to it + if APPLY(f,nil) + then + if npEqKey str1 and (npEqKey "BACKSET" or true) + and (APPLY(f,nil) or npTrap()) + then + a:=$stack + $stack:=nil + while npEqKey str1 and (npEqKey "BACKSET" or true) and + (APPLY(f,nil) or npTrap()) repeat 0 + $stack:=cons(NREVERSE $stack,a) + npPush FUNCALL(g, [npPop3(),npPop2(),:npPop1()]) + else + npPush FUNCALL(g, [npPop1()]) + else npPush FUNCALL(g, []) + + +++ rewrite flets, using global scoping +$npPParg := nil + +npPPff() == + FUNCALL $npPParg and npPush [npPop1()] + +npPPf() == + npSemiListing function npPPff + +npPPg() == + npListAndRecover function npPPf + and npPush pfAppend npPop1() + +npPP(f) == + $npPParg := f + npParened function npPPf + or npPileBracketed function npPPg and + npPush pfEnSequence npPop1() + or FUNCALL f + +++ rewrite flets, using global scoping +$npPCff := nil + +npPCff() == + FUNCALL $npPCff and npPush [npPop1()] + +npPCg() == + npListAndRecover function npPCff + and npPush pfAppend npPop1() + +npPC(f) == + $npPCff := f + npPileBracketed function npPCg and + npPush pfEnSequence npPop1() + or FUNCALL f + + +-- s must transform the head of the stack + +npAnyNo s== + while APPLY(s,nil) repeat 0 + true + +npAndOr(keyword,p,f)== + npEqKey keyword and (APPLY(p,nil) or npTrap()) + and npPush FUNCALL(f, npPop1()) + +npRightAssoc(o,p)== + a:=npState() + if APPLY(p,nil) + then + while npInfGeneric o and (npRightAssoc(o,p) + or (npPush pfApplication(npPop2(),npPop1());false)) repeat + npPush pfInfApplication(npPop2(),npPop2(),npPop1()) + true + else + npRestore a + false + +-- p o p o p o p = (((p o p) o p) o p) +-- p o p o = (p o p) o + +npLeftAssoc(operations,parser)== + if APPLY(parser,nil) + then + while npInfGeneric(operations) + and (APPLY(parser,nil) or + (npPush pfApplication(npPop2(),npPop1());false)) + repeat + npPush pfInfApplication(npPop2(),npPop2(),npPop1()) + true + else false + +npInfixOp()== + EQ(CAAR $stok,"key") and + GETL($ttok,"INFGENERIC") and npPushId() + +npInfixOperator()== npInfixOp() or + a:=npState() + b:=$stok + npEqKey "'" and npInfixOp() => + npPush pfSymb (npPop1 (),tokPosn b) + npRestore a + npEqKey "BACKQUOTE" and npInfixOp() => + a:=npPop1() + npPush tokConstruct("idsy",tokPart a,tokPosn a) + npRestore a + false + +npInfKey s== EQ(CAAR $stok,"key") and MEMQ($ttok,s) and npPushId() + +npDDInfKey s== + npInfKey s or + a:=npState() + b:=$stok + npEqKey "'" and npInfKey s => + npPush pfSymb (npPop1 () ,tokPosn b) + npRestore a + npEqKey "BACKQUOTE" and npInfKey s => + a:=npPop1() + npPush tokConstruct("idsy",tokPart a,tokPosn a) + npRestore a + false + +npInfGeneric s== npDDInfKey s and + (npEqKey "BACKSET" or true) + +npConditional f== + if npEqKey "IF" and (npLogical() or npTrap()) and + (npEqKey "BACKSET" or true) + then + if npEqKey "SETTAB" + then if npEqKey "THEN" + then (APPLY(f,nil) or npTrap()) and npElse(f) + and npEqKey "BACKTAB" + else npMissing "then" + else if npEqKey "THEN" + then (APPLY(f,nil) or npTrap()) and npElse(f) + else npMissing "then" + else false + +npElse(f)== + a:=npState() + if npBacksetElse() + then (APPLY(f,nil) or npTrap()) and + npPush pfIf(npPop3(),npPop2(),npPop1()) + else + npRestore a + npPush pfIfThenOnly(npPop2(),npPop1()) + +npBacksetElse()== + if npEqKey "BACKSET" + then npEqKey "ELSE" + else npEqKey "ELSE" + +npWConditional f== + if npConditional f + then npPush pfTweakIf npPop1() + else false + +-- Parsing functions + +-- peek for keyword s, no advance of token stream + +npEqPeek s == EQ(CAAR $stok,"key") and EQ(s,$ttok) + +-- test for keyword s, if found advance token stream + +npEqKey s == + EQ(CAAR $stok,"key") and EQ(s,$ttok) and npNext() + +$npTokToNames:= ["~","#","[]","{}", "[||]","{||}"] + +npId() == + EQ(CAAR $stok,"id") => + npPush $stok + npNext() + EQ(CAAR $stok,"key") and MEMQ($ttok,$npTokToNames)=> + npPush tokConstruct("id",$ttok,tokPosn $stok) + npNext() + false + +npSymbolVariable()== + a:=npState() + npEqKey "BACKQUOTE" and npId() => + a:=npPop1() + npPush tokConstruct("idsy",tokPart a,tokPosn a) + npRestore a + false + +npName()==npId() or npSymbolVariable() + +npConstTok() == + MEMQ(tokType $stok, '(integer string char float command)) => + npPush $stok + npNext() + npEqPeek "'" => + a:=$stok + b:=npState() + npNext() + if + npPrimary1() and npPush pfSymb(npPop1(),tokPosn a) + then true + else + npRestore b + false + false + + +npPrimary1() == + npEncAp function npAtom1 or + npLet() or + npFix() or + npMacro() or + npBPileDefinition() or npDefn() or + npRule() + +npPrimary2()== npEncAp function npAtom2 -- or npBPileDefinition() + or npAdd(pfNothing()) or npWith(pfNothing()) + + +npAtom1()== npPDefinition() or ((npName() or npConstTok() or + npDollar() or npBDefinition()) and npFromdom()) + +npAtom2()== (npInfixOperator() or npAmpersand() or npPrefixColon()) + and npFromdom() + +npDollar()== npEqPeek "$" and + npPush tokConstruct("id","$",tokPosn $stok) + npNext() + +npPrefixColon()== npEqPeek "COLON" and + npPush tokConstruct("id",":",tokPosn $stok) + npNext() + +-- silly + +npEncAp(f)== APPLY(f,nil) and npAnyNo function npEncl + and npFromdom() + + +npEncl()== npBDefinition() and npPush pfApplication(npPop2(),npPop1()) + +npFromdom()== + npEqKey "$" and (npApplication() or npTrap()) + and npFromdom1 npPop1() and npPush pfFromDom(npPop1(),npPop1()) + or true + +npFromdom1 c== + npEqKey "$" and (npApplication() or npTrap()) + and npFromdom1 npPop1() and npPush pfFromDom(npPop1(),c) + or npPush c + + +npPrimary()== npPrimary1() or npPrimary2() + +npDotted f== APPLY(f,nil) and npAnyNo function npSelector + +npSelector()== + npEqKey "DOT" and (npPrimary() or npTrap()) and + npPush(pfApplication(npPop2(),npPop1())) + +npApplication()== + npDotted function npPrimary and + (npApplication2() and + npPush(pfApplication(npPop2(),npPop1())) or true) + + +npApplication2()== + npDotted function npPrimary1 and + (npApplication2() and + npPush(pfApplication(npPop2(),npPop1())) or true) + +npTypedForm1(sy,fn) == + npEqKey sy and (npType() or npTrap()) and + npPush FUNCALL(fn,npPop2(),npPop1()) + +npTypedForm(sy,fn) == + npEqKey sy and (npApplication() or npTrap()) and + npPush FUNCALL(fn,npPop2(),npPop1()) + +npRestrict() == npTypedForm("AT",function pfRestrict) + +npCoerceTo() == npTypedForm("COERCE",function pfCoerceto) + +npColonQuery() == npTypedForm("ATAT",function pfRetractTo) + +npPretend() == npTypedForm("PRETEND",function pfPretend) + +npTypeStyle()== + npCoerceTo() or npRestrict() or npPretend() or npColonQuery() + +npTypified ()==npApplication() and npAnyNo function npTypeStyle + +npTagged() == npTypedForm1("COLON",function pfTagged) + +npColon () == npTypified() and npAnyNo function npTagged + +npPower() == npRightAssoc('(POWER CARAT),function npColon) + +npProduct()== + npLeftAssoc('(TIMES SLASH BACKSLASH SLASHSLASH + BACKSLASHBACKSLASH SLASHBACKSLASH BACKSLASHSLASH ) + ,function npPower) + +npRemainder()== + npLeftAssoc('(REM QUO ) ,function npProduct) + +npTerm()== + npInfGeneric '(MINUS PLUS) and (npRemainder() + and npPush(pfApplication(npPop2(),npPop1())) or true) + or npRemainder() + + +npSum()==npLeftAssoc('(PLUS MINUS),function npTerm) + +npArith()==npLeftAssoc('(MOD),function npSum) + +npSegment()== npEqPeek "SEG" and npPushId() and npFromdom() + +npInterval()== + npArith() and + (npSegment() and ((npEqPeek "BAR" + and npPush(pfApplication(npPop1(),npPop1()))) or + (npArith() and npPush(pfInfApplication(npPop2(),npPop2(),npPop1()))) + or npPush(pfApplication(npPop1(),npPop1()))) or true) + +npBy()== npLeftAssoc ('(BY),function npInterval) + +npAmpersand()== npEqKey "AMPERSAND" and (npName() or npTrap()) +npAmpersandFrom()== npAmpersand() and npFromdom() + +npSynthetic()== + if npBy() + then + while npAmpersandFrom() and (npBy() or + (npPush pfApplication(npPop2(),npPop1());false)) repeat + npPush pfInfApplication(npPop2(),npPop2(),npPop1()) + true + else false + +npRelation()== + npLeftAssoc ('(EQUAL NOTEQUAL LT LE GT GE OANGLE CANGLE), + function npSynthetic) + +npQuiver() == npRightAssoc('(ARROW LARROW),function npRelation) +npDiscrim() == npLeftAssoc ('(CASE HAS), function npQuiver) + +npDisjand() == npLeftAssoc('(AND ),function npDiscrim) + +npLogical() == npLeftAssoc('(OR ),function npDisjand) +npSuch() == npLeftAssoc( '(BAR),function npLogical) +npMatch() == npLeftAssoc ('(IS ISNT ), function npSuch) + +npType() == npMatch() and + a:=npPop1() + npWith(a) or npPush a + +npADD() == npType() and + a:=npPop1() + npAdd(a) or npPush a + +npConditionalStatement()==npConditional function npQualifiedDefinition + +npExpress1()==npConditionalStatement() or npADD() + +npCommaBackSet()== npEqKey "COMMA" and (npEqKey "BACKSET" or true) + +npExpress()== + npExpress1() and + (npIterators() and + npPush pfCollect (npPop2(),pfListOf npPop1()) or true) + +npZeroOrMore f== + APPLY(f,nil)=> + a:=$stack + $stack:=nil + while APPLY(f,nil) repeat 0 + $stack:=cons(NREVERSE $stack,a) + npPush cons(npPop2(),npPop1()) + npPush nil + true + +npIterators()== + npForIn() and npZeroOrMore function npIterator + and npPush cons(npPop2(),npPop1()) or + npWhile() and (npIterators() and + npPush cons(npPop2(),npPop1()) or npPush [npPop1()]) + +npIterator()== npForIn() or npSuchThat() or npWhile() + +npStatement()== + npExpress() or + npLoop() or + npIterate() or + npReturn() or + npBreak() or + npFree() or + npImport() or + npInline() or + npLocal() or + npExport() or + npTyping() or + npVoid() + +npBackTrack(p1,p2,p3)== + a:=npState() + APPLY(p1,nil) => + npEqPeek p2 => + npRestore a + APPLY(p3,nil) or npTrap() + true + false + +npMDEF()== npBackTrack(function npStatement,"MDEF",function npMDEFinition) + +npMDEFinition() == npPP function npMdef + +npAssign()== npBackTrack(function npMDEF,"BECOMES",function npAssignment) + +npAssignment()== + npAssignVariable() and + (npEqKey "BECOMES" or npTrap()) and + (npGives() or npTrap()) and + npPush pfAssign (npPop2(),npPop1()) + +npAssignVariableName()==npApplication() and + a:=npPop1() + if pfId? a + then + (npPush a and npDecl() or npPush pfTyped(npPop1(),pfNothing())) + else npPush a + +npAssignVariable()== npColon() and npPush pfListOf [npPop1()] + +npAssignVariablelist()== npListing function npAssignVariableName + +npExit()== npBackTrack(function npAssign,"EXIT",function npPileExit) + +npPileExit()== + npAssign() and (npEqKey "EXIT" or npTrap()) and + (npStatement() or npTrap()) + and npPush pfExit (npPop2(),npPop1()) + +npGives()== npBackTrack(function npExit,"GIVES",function npLambda) + +npDefinitionOrStatement()== + npBackTrack(function npGives,"DEF",function npDef) + +npVoid()== npAndOr("DO",function npStatement,function pfNovalue) + +npReturn()== + npEqKey "RETURN" and + (npExpress() or npPush pfNothing()) and + (npEqKey "FROM" and (npName() or npTrap()) and + npPush pfReturn (npPop2(),npPop1()) or + npPush pfReturnNoName npPop1()) +npLoop()== + npIterators() and + (npCompMissing "REPEAT" and + (npAssign() or npTrap()) and + npPush pfLp(npPop2(),npPop1())) + or + npEqKey "REPEAT" and (npAssign() or npTrap()) and + npPush pfLoop1 npPop1 () + +npSuchThat()==npAndOr("BAR",function npLogical,function pfSuchthat) + +npWhile()==npAndOr ("WHILE",function npLogical,function pfWhile) + +npForIn()== + npEqKey "FOR" and (npVariable() or npTrap()) and (npCompMissing "IN") + and ((npBy() or npTrap()) and + npPush pfForin(npPop2(),npPop1())) + +npBreak()== + npEqKey "BREAK" and npPush pfBreak pfNothing () + +npIterate()== + npEqKey "ITERATE" and npPush pfIterate pfNothing () + +npQualType()== + npType() and + npPush pfQualType(npPop1(),pfNothing()) + +npSQualTypelist()== npListing function npQualType + and npPush pfParts npPop1 () + +npQualTypelist()== npPC function npSQualTypelist + and npPush pfUnSequence npPop1 () + +npImport()==npAndOr("IMPORT",function npQualTypelist,function pfImport) + +npInline()==npAndOr("INLINE",function npQualTypelist,function pfInline) + +npLocalDecl()== npEqKey "COLON" and (npType() or npTrap()) and + npPush pfSpread (pfParts npPop2(),npPop1()) or + npPush pfSpread (pfParts npPop1(),pfNothing()) + +npLocalItem()==npTypeVariable() and npLocalDecl() + +npLocalItemlist()== npPC function npSLocalItem + and npPush pfUnSequence npPop1 () + +npSLocalItem()== npListing function npLocalItem + and npPush pfAppend pfParts npPop1() + +npFree()== npEqKey "FREE" and (npLocalItemlist() or npTrap()) + and npPush pfFree npPop1() + +npLocal()== npEqKey "local" and (npLocalItemlist() or npTrap()) + and npPush pfLocal npPop1() +npExport()== npEqKey "EXPORT" and (npLocalItemlist() or npTrap()) + and npPush pfExport npPop1() + +npLet()== npLetQualified function npDefinitionOrStatement + +npDefn()== npEqKey "DEFN" and npPP function npDef + +npFix()== npEqKey "FIX" and npPP function npDef + and npPush pfFix npPop1 () + +npMacro()== npEqKey "MACRO" and npPP function npMdef + +npRule()== npEqKey "RULE" and npPP function npSingleRule + +npAdd(extra)== + npEqKey "ADD" and + a:=npState() + npDefinitionOrStatement() or npTrap() + npEqPeek "IN" => + npRestore a + (npVariable() or npTrap()) and + npCompMissing "IN" and + (npDefinitionOrStatement() or npTrap()) and + npPush pfAdd(npPop2(),npPop1(),extra) + npPush pfAdd(pfNothing(),npPop1(),extra) + +npDefaultValue()== + npEqKey "DEFAULT" and + (npDefinitionOrStatement() or npTrap()) + and npPush [pfAdd(pfNothing(),npPop1(),pfNothing())] + +npWith(extra)== + npEqKey "WITH" and + a:=npState() + npCategoryL() or npTrap() + npEqPeek "IN" => + npRestore a + (npVariable() or npTrap()) and + npCompMissing "IN" and + (npCategoryL() or npTrap()) and + npPush pfWith(npPop2(),npPop1(),extra) + npPush pfWith(pfNothing(),npPop1(),extra) + +npCategoryL()== npCategory() and npPush pfUnSequence npPop1 () + +pfUnSequence x== + pfSequence? x => pfListOf pfAppend pf0SequenceArgs x + pfListOf x + +npCategory()== npPP function npSCategory + +npSCategory()== + if npWConditional function npCategoryL + then npPush [npPop1()] + else + if npDefaultValue() + then true + else + a:=npState() + if npPrimary() + then if npEqPeek "COLON" + then + npRestore a + npSignature() + else + npRestore a + npApplication() and npPush [pfAttribute (npPop1())] + or npTrap() + + else false + + +npSignatureDefinee()== + npName() or npInfixOperator() or npPrefixColon() + + +npSigDecl()== npEqKey "COLON" and (npType() or npTrap()) and + npPush pfSpread (pfParts npPop2(),npPop1()) + +npSigItem()==npTypeVariable() and (npSigDecl() or npTrap()) + +npSigItemlist()== npListing function npSigItem + and npPush pfListOf pfAppend pfParts npPop1() + +npSignature()== + npSigItemlist() and + npPush pfWDec(pfNothing(),npPop1()) + +npSemiListing (p)== + npListofFun(p,function npSemiBackSet,function pfAppend) + +npSemiBackSet()== npEqKey "SEMICOLON" and (npEqKey "BACKSET" or true) +npDecl()== npEqKey "COLON" and (npType() or npTrap()) and + npPush pfTyped (npPop2(),npPop1()) + +npVariableName()==npName() and + (npDecl() or npPush pfTyped(npPop1(),pfNothing())) + +npVariable()== npParenthesized function npVariablelist or + (npVariableName() and npPush pfListOf [npPop1()]) + +npVariablelist()== npListing function npVariableName + +npListing (p)==npList(p,"COMMA",function pfListOf) +npQualified(f)== + if FUNCALL f + then + while npEqKey "WHERE" and (npDefinition() or npTrap()) repeat + npPush pfWhere(npPop1(),npPop1()) + true + else npLetQualified f + +npLetQualified f== + npEqKey "LET" and + (npDefinition() or npTrap()) and + npCompMissing "IN" and + (FUNCALL f or npTrap()) and + npPush pfWhere(npPop2(),npPop1()) + + +npQualifiedDefinition()== + npQualified function npDefinitionOrStatement + +npTuple (p)== + npListofFun(p,function npCommaBackSet,function pfTupleListOf) +npComma()== npTuple function npQualifiedDefinition + +npQualDef()== npComma() and npPush [npPop1()] + +npDefinitionlist ()==npSemiListing(function npQualDef) + +npPDefinition ()== + npParenthesized function npDefinitionlist and + npPush pfEnSequence npPop1() + +npBDefinition()== npPDefinition() or + npBracketed function npDefinitionlist + +npPileDefinitionlist()== + npListAndRecover function npDefinitionlist + and npPush pfAppend npPop1() + + +npTypeVariable()== npParenthesized function npTypeVariablelist or + npSignatureDefinee() and npPush pfListOf [npPop1()] + +npTypeVariablelist()== npListing function npSignatureDefinee + +npTyping()== + npEqKey "DEFAULT" and (npDefaultItemlist() or npTrap()) + and npPush pfTyping npPop1() + +npDefaultItemlist()== npPC function npSDefaultItem + and npPush pfUnSequence npPop1 () + +npDefaultDecl()== npEqKey "COLON" and (npType() or npTrap()) and + npPush pfSpread (pfParts npPop2(),npPop1()) + +npDefaultItem()==npTypeVariable() and (npDefaultDecl() or npTrap()) + +npSDefaultItem()== npListing function npDefaultItem + and npPush pfAppend pfParts npPop1() + +npBPileDefinition()== + npPileBracketed function npPileDefinitionlist + and npPush pfSequence pfListOf npPop1 () + + +npLambda()== + (npVariable() and + ((npLambda() or npTrap()) and + npPush pfLam(npPop2(),npPop1()))) or + npEqKey "GIVES" and (npDefinitionOrStatement() or npTrap()) or + npEqKey "COLON" and (npType() or npTrap()) and + npEqKey "GIVES" and (npDefinitionOrStatement() or npTrap()) + and + npPush pfReturnTyped(npPop2(),npPop1()) + +npDef()== + npMatch() => + [op,arg,rt]:= pfCheckItOut(npPop1()) + npDefTail() or npTrap() + body:=npPop1() + null arg => npPush pfDefinition (op,body) + npPush pfDefinition (op,pfPushBody(rt,arg,body)) + false + +--npDefTail()== npEqKey "DEF" and npDefinitionOrStatement() +npDefTail()== (npEqKey "DEF" or npEqKey "MDEF") and npDefinitionOrStatement() + +npMdef()== + npQuiver() => + [op,arg]:= pfCheckMacroOut(npPop1()) + npDefTail() or npTrap() + body:=npPop1() + null arg => npPush pfMacro (op,body) + npPush pfMacro (op,pfPushMacroBody(arg,body)) + false + + +npSingleRule()== + npQuiver() => + npDefTail() or npTrap() + npPush pfRule (npPop2(),npPop1()) + false + +npDefinitionItem()== + npTyping() or + npImport() or + a:=npState() + npStatement() => + npEqPeek "DEF" => + npRestore a + npDef() + npRestore a + npMacro() or npDefn() + npTrap() + +npDefinition()== npPP function npDefinitionItem + and npPush pfSequenceToList npPop1 () + +pfSequenceToList x== + pfSequence? x => pfSequenceArgs x + pfListOf [x] + +--% Diagnostic routines + +npMissingMate(close,open)== + ncSoftError(tokPosn open, 'S2CY0008, []) + npMissing close + +npMissing s== + ncSoftError(tokPosn $stok,'S2CY0007, [PNAME s]) + THROW("TRAPPOINT","TRAPPED") + +npCompMissing s == npEqKey s or npMissing s + +npRecoverTrap()== + npFirstTok() + pos1 := tokPosn $stok + npMoveTo 0 + pos2 := tokPosn $stok + syIgnoredFromTo(pos1, pos2) + npPush [pfWrong(pfDocument ['"pile syntax error"],pfListOf [])] + + +npListAndRecover(f)== + a:=$stack + b:=nil + $stack:=nil + done:=false + c:=$inputStream + while not done repeat + found:=CATCH("TRAPPOINT",APPLY(f,nil)) + if found="TRAPPED" + then + $inputStream:=c + npRecoverTrap() + else if not found + then + $inputStream:=c + syGeneralErrorHere() + npRecoverTrap() + if npEqKey "BACKSET" + then + c:=$inputStream + else if npEqPeek "BACKTAB" + then + done:=true + else + $inputStream:=c + syGeneralErrorHere() + npRecoverTrap() + if npEqPeek "BACKTAB" + then done:=true + else + npNext() + c:=$inputStream + b:=cons(npPop1(),b) + $stack:=a + npPush NREVERSE b + +npMoveTo n== + if null $inputStream + then true + else + if npEqPeek "BACKTAB" + then if n=0 + then true + else (npNext();npMoveTo(n-1)) + else if npEqPeek "BACKSET" + then if n=0 + then true + else (npNext();npMoveTo n) + else if npEqKey "SETTAB" + then npMoveTo(n+1) + else (npNext();npMoveTo n) |