12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216 |
- package kawa.lang;
- import gnu.mapping.*;
- import gnu.expr.*;
- import gnu.kawa.reflect.*;
- import gnu.bytecode.ArrayClassLoader;
- import gnu.bytecode.ClassType;
- import gnu.bytecode.Field;
- import gnu.bytecode.Member;
- import gnu.bytecode.Type;
- import gnu.bytecode.ZipLoader;
- import gnu.text.SourceMessages;
- import gnu.lists.*;
- import gnu.kawa.lispexpr.*;
- import java.util.*;
- import gnu.kawa.functions.GetNamedPart;
- import gnu.kawa.functions.CompileNamedPart;
- import gnu.kawa.functions.MakeSplice;
- import gnu.kawa.functions.MultiplyOp;
- import gnu.kawa.functions.Expt;
- import gnu.kawa.xml.XmlNamespace;
- import gnu.math.DFloNum;
- import gnu.math.IntNum;
- import gnu.math.Unit;
- import gnu.text.Char;
- import gnu.text.SourceLocator;
- import gnu.text.StandardNamedChars;
- /* #ifdef enable:XML */
- import gnu.xml.NamespaceBinding;
- /* #endif */
- import kawa.standard.Scheme;
- import kawa.standard.require.DeclSetMapper;
- /** Used to translate from source to Expression.
- * The result has macros expanded, lexical names bound, etc, and is
- * ready for code generation.
- * This is sometimes called a "compilation environment",
- * but we modify it as we go along - there is a single Translator for
- * each top-level form.
- */
- public class Translator extends Compilation
- {
- // Global environment used to look for syntax/macros.
- private Environment env;
- /** Set if we're processing (as opposed to expanding)
- * a <code>define-syntax</code> or <code>defmacro</code>. */
- public Macro currentMacroDefinition;
- /** Innermost current scope of pattern variable,
- * from a <code>syntax-case</code>. */
- public PatternScope patternScope;
- public Declaration templateScopeDecl;
- /** A "mark" created for the current macro application.
- * This is (more-or-less) the mark specified by the syntax-case
- * specification (in r6rs-lib), applied to the output of a transformer.
- * However, instead of "applying" a mark to the transformer output,
- * we remember in the TemplateScope an object unique to the application.
- */
- Object currentMacroMark = null;
- /** A variable to hold the matched values for syntax-case
- * pattern variables. */
- public Declaration matchArray;
- /** A stack of aliases pushed by <code>pushRenamedAlias</code>. */
- private Stack<Declaration> renamedAliasStack;
- public Object pendingForm;
- public LambdaExp curMethodLambda;
- /* #ifdef enable:XML */
- public NamespaceBinding xmlElementNamespaces = NamespaceBinding.predefinedXML;
- /* #endif */
- public static final Declaration getNamedPartDecl;
- static {
- // Declare the special symbol $lookup$ (from the reader)
- // and bind it to getNamedPartDecl.
- String cname = "gnu.kawa.functions.GetNamedPart";
- String fname = "getNamedPart";
- getNamedPartDecl = Declaration.getDeclarationFromStatic(cname, fname);
- LispLanguage.getNamedPartLocation.setDeclaration(getNamedPartDecl);
- }
- private static Expression errorExp = new ErrorExp ("unknown syntax error");
- public Translator(Language language, SourceMessages messages,
- NameLookup lexical, Environment env) {
- super(language, messages, lexical);
- this.env = env;
- }
- public Translator(Language language, SourceMessages messages,
- NameLookup lexical) {
- super(language, messages, lexical);
- this.env = Environment.getCurrent();
- }
- @Override
- public final Environment getGlobalEnvironment() { return env; }
- public Expression parse (Object input)
- {
- return rewrite(input);
- }
- public final Expression rewrite_car (Pair pair, SyntaxForm syntax)
- {
- return rewrite_car(pair, syntax == null ? current_scope : syntax.getScope());
- }
- public final Expression rewrite_car (Pair pair, ScopeExp templateScope)
- {
- if (templateScope == current_scope
- || pair.getCar() instanceof SyntaxForm)
- return rewrite_car(pair, false);
- ScopeExp save_scope = setPushCurrentScope(templateScope);
- try
- {
- return rewrite_car(pair, false);
- }
- finally
- {
- setPopCurrentScope(save_scope);
- }
- }
- public final Expression rewrite_car (Pair pair, boolean function)
- {
- Object car = pair.getCar();
- if (pair instanceof PairWithPosition)
- return rewrite_with_position (car, function, (PairWithPosition) pair);
- else
- return rewrite (car, function);
- }
- /** Similar to rewrite_car.
- * However, we check for (quasiquote exp) specially, and handle that
- * directly. This is in case quasiquote isn't in scope.
- */
- public final Expression rewrite_car_for_lookup(Pair pair) {
- Object car = pair.getCar();
- if (car instanceof Pair) {
- Pair pcar = (Pair) car;
- if (pcar.getCar() == LispLanguage.quasiquote_sym) {
- Object pos = pushPositionOf(pair);
- Expression ret = Quote.quasiQuote.rewrite(pcar.getCdr(), this);
- popPositionOf(pos);
- return ret;
- }
- }
- return rewrite_car(pair, false);
- }
- Syntax currentSyntax;
- public Syntax getCurrentSyntax() { return currentSyntax; }
- /** The module instance containing the current macro.
- * This is only used temporarily, set when resolving a Declaration
- * bound to a macro, and used to set the macroContext field of the
- * TemplateScope created when expanding the macro's template(s). */
- Declaration macroContext;
- /**
- * Apply a Syntax object.
- * @param syntax the Syntax object whose rewrite method we call
- * @param form the syntax form (including the macro name)
- * @return the re-written form as an Expression object
- */
- Expression apply_rewrite (Syntax syntax, Pair form)
- {
- Expression exp = errorExp;
- Syntax saveSyntax = currentSyntax;
- currentSyntax = syntax;
- try
- {
- exp = syntax.rewriteForm(form, this);
- }
- finally
- {
- currentSyntax = saveSyntax;
- }
- return exp;
- }
- /** Check if declaraton is an alias for some other name.
- * This is needed to chase identifiers renamed for hygienic macro
- * expansion - see SyntaxRules.expand. */
- static ReferenceExp getOriginalRef(Declaration decl)
- {
- if (decl != null && decl.isAlias() && ! decl.isIndirectBinding())
- {
- Expression value = decl.getValue();
- if (value instanceof ReferenceExp)
- return (ReferenceExp) value;
- }
- return null;
- }
- public final boolean keywordsAreSelfEvaluating() {
- return ((LispLanguage) getLanguage()).keywordsAreSelfEvaluating();
- }
- public final boolean selfEvaluatingSymbol (Object obj)
- {
- return ((LispLanguage) getLanguage()).selfEvaluatingSymbol(obj);
- }
- /** True iff a form matches a literal symbol. */
- public final boolean matches(Object form, String literal)
- {
- return matches(form, null, literal);
- }
- public boolean matches(Object form, SyntaxForm syntax, String literal)
- {
- if (syntax != null)
- {
- // FIXME
- }
- if (form instanceof SyntaxForm)
- {
- // FIXME
- form = ((SyntaxForm) form).getDatum();
- }
- if (form instanceof SimpleSymbol && ! selfEvaluatingSymbol(form))
- {
- ReferenceExp rexp = getOriginalRef(lexical.lookup(form, -1));
- if (rexp != null)
- form = rexp.getSymbol();
- }
- return form instanceof SimpleSymbol
- && ((Symbol) form).getLocalPart() == literal;
- }
- public boolean matches(Object form, SyntaxForm syntax, Symbol literal)
- {
- if (syntax != null)
- {
- // FIXME
- }
- if (form instanceof SyntaxForm)
- {
- // FIXME
- form = ((SyntaxForm) form).getDatum();
- }
- if (form instanceof SimpleSymbol && ! selfEvaluatingSymbol(form))
- {
- ReferenceExp rexp = getOriginalRef(lexical.lookup(form, -1));
- if (rexp != null)
- form = rexp.getSymbol();
- }
- return form == literal;
- }
- public Object matchQuoted (Pair pair)
- {
- if (matches(pair.getCar(), LispLanguage.quote_str)
- && pair.getCdr() instanceof Pair
- && (pair = (Pair) pair.getCdr()).getCdr() == LList.Empty)
- return pair.getCar();
- return null;
- }
- public Declaration lookup(Object name, int namespace)
- {
- Declaration decl = lexical.lookup(name, namespace);
- if (decl != null && getLanguage().hasNamespace(decl, namespace))
- return decl;
- return currentModule().lookup(name, getLanguage(), namespace);
- }
- /** Find global Declaration, creating one if not found. */
- public Declaration lookupGlobal(Object name)
- {
- return lookupGlobal(name, -1);
- }
- /** Find global Declaration, creating one if not found. */
- public Declaration lookupGlobal(Object name, int namespace)
- {
- ModuleExp module = currentModule();
- Declaration decl = module.lookup(name, getLanguage(), namespace);
- if (decl == null)
- {
- decl = module.getNoDefine(name);
- decl.setIndirectBinding(true);
- }
- return decl;
- }
- /** Check if a Declaration is bound to a Syntax.
- * @param decl the Declaration to check
- * @return the Syntax bound to decl, or null.
- * In the former case, macroContext may be set as a side effect.
- */
- Syntax check_if_Syntax (Declaration decl)
- {
- Declaration d = Declaration.followAliases(decl);
- Object obj = null;
- Expression dval = d.getValue();
- if (dval != null && d.getFlag(Declaration.IS_SYNTAX))
- {
- try
- {
- if (decl.getValue() instanceof ReferenceExp)
- {
- Declaration context
- = ((ReferenceExp) decl.getValue()).contextDecl();
- if (context != null)
- macroContext = context;
- else if (current_scope instanceof TemplateScope)
- macroContext = ((TemplateScope) current_scope).macroContext;
- }
- else if (current_scope instanceof TemplateScope)
- macroContext = ((TemplateScope) current_scope).macroContext;
- obj = dval.eval(env);
- }
- catch (Error ex)
- {
- ex.printStackTrace();
- throw ex;
- }
- catch (Throwable ex)
- {
- ex.printStackTrace();
- error('e', "unable to evaluate macro for "+decl.getSymbol());
- }
- }
- else if (decl.getFlag(Declaration.IS_SYNTAX) && ! decl.needsContext())
- {
- StaticFieldLocation loc = StaticFieldLocation.make(decl);
- obj = loc.get(null);
- }
- return obj instanceof Syntax ? (Syntax) obj : null;
- }
- public Expression rewrite_pair (Pair p, boolean function)
- {
- Object p_car = p.getCar();
- Expression func;
- boolean useHelper = true;
- if (p_car instanceof Pair
- && ((Pair) p_car).getCar() == LispLanguage.splice_sym) {
- func = gnu.kawa.reflect.MakeAnnotation.makeAnnotationMaker
- (rewrite_car((Pair) ((Pair) p_car).getCdr(), false));
- useHelper = false;
- }
- else
- func = rewrite_car (p, true);
- Object proc = null;
- if (func instanceof QuoteExp)
- {
- proc = func.valueIfConstant();
- if (proc instanceof Syntax)
- return apply_rewrite((Syntax) proc, p);
- }
- ReferenceExp ref = null;
- if (func instanceof ReferenceExp)
- {
- ref = (ReferenceExp) func;
- Declaration decl = ref.getBinding();
- if (decl == null)
- {
- Object sym = ref.getSymbol();
- Symbol symbol;
- String name;
- if (sym instanceof Symbol && ! selfEvaluatingSymbol(sym))
- {
- symbol = (Symbol) sym;
- name = symbol.getName();
- }
- else
- {
- name = sym.toString();
- symbol = env.getSymbol(name);
- }
- proc = env.get(symbol,
- getLanguage().hasSeparateFunctionNamespace()
- ? EnvironmentKey.FUNCTION
- : null,
- null);
- if (proc instanceof Syntax)
- return apply_rewrite ((Syntax) proc, p);
- if (proc instanceof AutoloadProcedure)
- {
- try
- {
- proc = ((AutoloadProcedure) proc).getLoaded();
- }
- catch (RuntimeException ex)
- {
- proc = null;
- }
- }
- }
- else
- {
- Declaration saveContext = macroContext;
- Syntax syntax = check_if_Syntax (decl);
- if (syntax != null)
- {
- Expression e = apply_rewrite (syntax, p);
- macroContext = saveContext;
- return e;
- }
- }
- ref.setProcedureName(true);
- if (getLanguage().hasSeparateFunctionNamespace())
- func.setFlag(ReferenceExp.PREFER_BINDING2);
- }
- boolean isNamedPartDecl = func instanceof ReferenceExp
- && (((ReferenceExp) func).getBinding()==getNamedPartDecl);
- if (isNamedPartDecl)
- useHelper = false;
- Object cdr = p.getCdr();
- int cdr_length = listLength(cdr);
- if (cdr_length < 0)
- return syntaxError
- ("improper list (circular or dotted) is not allowed here");
- Expression applyFunction = useHelper ? applyFunction(func) : null;
- Stack vec = new Stack();
- if (applyFunction != null) {
- vec.add(func);
- func = applyFunction;
- }
- ScopeExp save_scope = current_scope;
- int first_keyword = -1;
- int last_keyword = -1;
- boolean bad_keyword_reported = false;
- int firstSpliceArg = -1;
- int i = 0;
- while (cdr != LList.Empty)
- {
- if (cdr instanceof SyntaxForm)
- {
- SyntaxForm sf = (SyntaxForm) cdr;
- cdr = sf.getDatum();
- // I.e. first time do equivalent of setPushCurrentScope
- if (current_scope == save_scope)
- lexical.pushSaveTopLevelRedefs();
- setCurrentScope(sf.getScope());
- }
- Object save_pos = pushPositionOf(cdr);
- Pair cdr_pair = (Pair) cdr;
- Object cdr_car = cdr_pair.getCar();
- Object cdr_cdr = cdr_pair.getCdr();
- Expression arg;
- if (cdr_car instanceof Keyword) {
- if (first_keyword < 0) {
- first_keyword = i;
- last_keyword = i - 2; // To suppress incorrect warnings
- }
- if (bad_keyword_reported)
- ;
- else if (keywordsAreSelfEvaluating())
- last_keyword = i;
- else if (i == last_keyword + 1 || i + 1 == cdr_length) {
- bad_keyword_reported = true;
- error('w', "missing value after unquoted keyword");
- } else if (i != last_keyword + 2) {
- bad_keyword_reported = true;
- error('w', "keyword separated from other keyword arguments");
- } else
- last_keyword = i;
- arg = QuoteExp.getInstance(cdr_car, this);
- arg.setFlag(QuoteExp.IS_KEYWORD);
- } else if (cdr_cdr instanceof Pair
- // FIXME should check binding for ... is builtin ...
- && ((Pair) cdr_cdr).getCar() == LispLanguage.dots3_sym) {
- LambdaExp dotsLambda = new LambdaExp();
- pushScanContext(dotsLambda);
- dotsLambda.body = rewrite_car(cdr_pair, false);
- ScanContext scanContext = getScanContext();
- LinkedHashMap<Declaration,Declaration> sdecls
- = scanContext.decls;
- int nseqs = sdecls.size();
- ArrayList<Expression> scanExps = scanContext.scanExpressions;
- int nexps = scanExps == null ? 0 : scanExps.size();
- Expression[] subargs = new Expression[nseqs + nexps + 1];
- subargs[0] = dotsLambda;
- popScanContext();
- Iterator<Declaration> sit = sdecls.keySet().iterator();
- int j = 1;
- while (sit.hasNext()) {
- Declaration sdecl = sit.next();
- if (curScanNesting() > 0) {
- sdecl = getScanContext().addSeqDecl(sdecl);
- }
- ReferenceExp rexp = new ReferenceExp(sdecl);
- subargs[j++] = rexp;
- }
- for (int k = 0; k < nexps; k++) {
- subargs[j++] = scanExps.get(k);
- }
- arg = new ApplyExp(Scheme.map, subargs);
- arg = new ApplyExp(MakeSplice.quoteInstance, arg);
- cdr_cdr = ((Pair) cdr_cdr).getCdr();
- if (firstSpliceArg < 0)
- firstSpliceArg = i + (applyFunction != null ? 1 : 0);
- } else {
- Object cdr_car_car;
- if (cdr_car instanceof Pair
- && ((cdr_car_car = ((Pair) cdr_car).getCar()) == LispLanguage.splice_sym
- || cdr_car_car == LispLanguage.splice_colon_sym)) {
- arg = rewrite_car((Pair) ((Pair) cdr_car).getCdr(), false);
- QuoteExp splicer = cdr_car_car == LispLanguage.splice_sym
- ? MakeSplice.quoteInstance
- : MakeSplice.quoteKeywordsAllowedInstance;
- arg = new ApplyExp(splicer, arg);
- if (firstSpliceArg < 0)
- firstSpliceArg = i + (applyFunction != null ? 1 : 0);
- }
- else
- arg = rewrite_car (cdr_pair, false);
- }
- i++;
- vec.addElement(arg);
- cdr = cdr_cdr;
- popPositionOf(save_pos);
- }
- Expression[] args = new Expression[vec.size()];
- vec.copyInto(args);
- if (save_scope != current_scope)
- setPopCurrentScope(save_scope);
- if (isNamedPartDecl)
- return rewrite_lookup(args[0], args[1], function);
- ApplyExp app = new ApplyExp(func, args);
- app.firstSpliceArg = firstSpliceArg;
- if (first_keyword >= 0)
- {
- app.numKeywordArgs = (last_keyword - first_keyword) / 2 + 1;
- app.firstKeywordArgIndex = first_keyword + (applyFunction != null ? 2 : 1);
- }
- return app;
- }
- public Expression rewrite_lookup(Expression part1, Expression part2, boolean function) {
- Symbol sym = namespaceResolve(part1, part2);
- if (sym != null)
- return rewrite(sym, function);
- // FIXME don't copy the args array in makeExp ...
- return CompileNamedPart.makeExp(part1, part2);
- }
- public Namespace namespaceResolvePrefix (Expression context)
- {
- if (context instanceof ReferenceExp)
- {
- ReferenceExp rexp = (ReferenceExp) context;
- Declaration decl = rexp.getBinding();
- Object val;
- if (decl == null || decl.getFlag(Declaration.IS_UNKNOWN))
- {
- Object rsym = rexp.getSymbol();
- Symbol sym = rsym instanceof Symbol ? (Symbol) rsym
- : env.getSymbol(rsym.toString());
- val = env.get(sym, null);
- }
- else if (decl.isNamespaceDecl())
- {
- val = decl.getConstantValue();
- }
- else
- val = null;
- if (val instanceof Namespace)
- {
- Namespace ns = (Namespace) val;
- String uri = ns.getName();
- if (uri != null && uri.startsWith("class:"))
- return null;
- return ns;
- }
- }
- return null;
- }
- public Symbol namespaceResolve (Namespace ns, Expression member)
- {
- if (ns != null && member instanceof QuoteExp)
- {
- String mem = ((QuoteExp) member).getValue().toString().intern();
- return ns.getSymbol(mem);
- }
- return null;
- }
- public Symbol namespaceResolve (Expression context, Expression member)
- {
- return namespaceResolve(namespaceResolvePrefix(context), member);
- }
- public static Object stripSyntax (Object obj)
- {
- while (obj instanceof SyntaxForm)
- obj = ((SyntaxForm) obj).getDatum();
- return obj;
- }
- public static Object safeCar (Object obj)
- {
- while (obj instanceof SyntaxForm)
- obj = ((SyntaxForm) obj).getDatum();
- if (! (obj instanceof Pair))
- return null;
- return stripSyntax(((Pair) obj).getCar());
- }
- public static Object safeCdr (Object obj)
- {
- while (obj instanceof SyntaxForm)
- obj = ((SyntaxForm) obj).getDatum();
- if (! (obj instanceof Pair))
- return null;
- return stripSyntax(((Pair) obj).getCdr());
- }
- /** Returns the length of a syntax list.
- * Returns Integer.MIN_VALUE for cyclic lists.
- * For impure lists returns the negative of one more than
- * the number of pairs before the "dot".
- * Similar to LList.listLength, but handles SyntaxForm more efficiently. */
- public static int listLength(Object obj)
- {
- // Based on list-length implementation in
- // Guy L Steele jr: "Common Lisp: The Language", 2nd edition, page 414
- int n = 0;
- Object slow = obj;
- Object fast = obj;
- for (;;)
- {
- // 'n' is number of previous Pairs before 'fast' cursor.
- while (fast instanceof SyntaxForm)
- fast = ((SyntaxForm) fast).getDatum();
- while (slow instanceof SyntaxForm)
- slow = ((SyntaxForm) slow).getDatum();
- if (fast == LList.Empty)
- return n;
- if (! (fast instanceof Pair))
- return -1-n;
- n++;
- Object next = ((Pair) fast).getCdr();
- while (next instanceof SyntaxForm)
- next = ((SyntaxForm) next).getDatum();
- if (next == LList.Empty)
- return n;
- if (! (next instanceof Pair))
- return -1-n;
- slow = ((Pair)slow).getCdr();
- fast = ((Pair)next).getCdr();
- n++;
- if (fast == slow)
- return Integer.MIN_VALUE;
- }
- }
- public void rewriteInBody (Object exp)
- {
- if (exp instanceof SyntaxForm)
- {
- SyntaxForm sf = (SyntaxForm) exp;
- ScopeExp save_scope = setPushCurrentScope(sf.getScope());
- try
- {
- rewriteInBody(sf.getDatum());
- }
- finally
- {
- setPopCurrentScope(save_scope);
- }
- }
- else if (exp instanceof ValuesFromLList)
- {
- // Optimization of following case.
- // More importantly, we make use of the line number information.
- for (Object vs = ((ValuesFromLList) exp).values;
- vs != LList.Empty; )
- {
- Pair p = (Pair) vs;
- pushForm(rewrite_car(p, false));
- vs = p.getCdr();
- }
- }
- else if (exp instanceof Values)
- {
- Object[] vals = ((Values) exp).getValues();
- for (int i = 0; i < vals.length; i++)
- rewriteInBody(vals[i]);
- }
- else {
- Expression e = rewrite(exp, false);
- setLineOf(e);
- pushForm(e);
- }
- }
- public int getCompletions(Environment env,
- String nameStart, Object property,
- String namespaceUri,
- List<? super String> matches) {
- LocationEnumeration e = env.enumerateAllLocations();
- int count = 0;
- while (e.hasMoreElements()) {
- Location loc = e.nextLocation();
- Symbol sym = loc.getKeySymbol();
- String local = sym == null ? null : sym.getLocalPart();
- if (local != null && local.startsWith(nameStart)
- && property == loc.getKeyProperty()
- && namespaceUri == sym.getNamespaceURI()) {
- count++;
- matches.add(local);
- }
- }
- return count;
- }
- public Object namespaceResolve(Object name) {
- Object prefix = null;
- Expression part2 = null;
- Pair p;
- if (name instanceof Pair
- && safeCar(p = (Pair) name) == LispLanguage.lookup_sym
- && p.getCdr() instanceof Pair
- && (p = (Pair) p.getCdr()).getCdr() instanceof Pair) {
- prefix = namespaceResolve(p.getCar());
- if (! (stripSyntax(prefix) instanceof Symbol))
- return name;
- part2 = rewrite_car_for_lookup((Pair) p.getCdr());
- }
- else if (name instanceof Symbol) {
- Symbol s = (Symbol) name;
- if (s.hasUnknownNamespace()) {
- String loc = s.getLocalPart();
- prefix = Symbol.valueOf(s.getPrefix());
- part2 = QuoteExp.getInstance(Symbol.valueOf(s.getLocalPart()));
- }
- }
- if (part2 != null) {
- Expression part1 = rewrite(prefix);
- Symbol sym = namespaceResolve(part1, part2);
- if (sym != null)
- return sym;
- String combinedName = CompileNamedPart.combineName(part1, part2);
- if (combinedName != null)
- return Namespace.EmptyNamespace.getSymbol(combinedName);
- }
- return name;
- }
- /**
- * Re-write a Scheme expression in S-expression format into internal form.
- */
- public Expression rewrite(Object exp) {
- return rewrite(exp, 'N');
- }
- /**
- * Re-write a Scheme expression in S-expression format into internal form.
- */
- public Expression rewrite(Object exp, boolean function) {
- return rewrite(exp, function ? 'F' : 'N');
- }
- /** Re-write a Scheme expression in S-expression format into internal form.
- * @param mode either 'N' (normal), 'F' (function application context),
- * or 'M' (macro-checking).
- */
- public Expression rewrite(Object exp, char mode) {
- if (exp instanceof SyntaxForm) {
- SyntaxForm sf = (SyntaxForm) exp;
- ScopeExp save_scope = setPushCurrentScope(sf.getScope());
- try {
- Expression s = rewrite(sf.getDatum(), mode);
- return s;
- } finally {
- setPopCurrentScope(save_scope);
- }
- }
- boolean function = mode != 'N';
- if (exp instanceof Pair) {
- Expression e = rewrite_pair((Pair) exp, function);
- setLineOf(e);
- return e;
- } else if (exp instanceof Symbol && ! selfEvaluatingSymbol(exp)) {
- Symbol s = (Symbol) exp;
- // Check if we're handling a completion request.
- int complete = s.getLocalName()
- .indexOf(CommandCompleter.COMPLETE_REQUEST);
- boolean separate = getLanguage().hasSeparateFunctionNamespace();
- if (complete >= 0) {
- List<String> candidates = new ArrayList<String>();
- String prefix = s.toString().substring(0, complete);
- Object property = function && separate ? EnvironmentKey.FUNCTION
- : null;
- int symspace = function ? Language.FUNCTION_NAMESPACE
- : Language.VALUE_NAMESPACE;
- getCompletions(env, prefix, property, s.getNamespaceURI(),
- candidates);
- lexical.getCompletingSymbols(prefix, symspace,
- candidates);
- throw new CommandCompleter(complete, candidates,
- prefix, prefix.length(), this);
- }
- if (s.hasUnknownNamespace()) {
- String loc = s.getLocalPart();
- return rewrite_lookup(rewrite(Symbol.valueOf(s.getPrefix()), false),
- QuoteExp.getInstance(Symbol.valueOf(s.getLocalPart())),
- function);
- }
- Declaration decl = lexical.lookup(exp, function);
- Declaration cdecl = null;
- // If we're nested inside a class (in a ClassExp) then the field
- // and methods names of this class and super-classes/interfaces
- // need to be searched.
- ScopeExp scope = current_scope;
- int decl_nesting = decl == null ? -1 : ScopeExp.nesting(decl.context);
- String dname;
- if (exp instanceof SimpleSymbol)
- dname = exp.toString();
- else {
- dname = null;
- scope = null;
- }
- for (;scope != null; scope = scope.getOuter()) {
- if (scope instanceof LambdaExp
- && scope.getOuter() instanceof ClassExp // redundant? FIXME
- && ((LambdaExp) scope).isClassMethod()
- && mode != 'M') {
- if (decl_nesting >= ScopeExp.nesting(scope.getOuter()))
- break;
- LambdaExp caller = (LambdaExp) scope;
- ClassExp cexp = (ClassExp) scope.getOuter();
- ClassType ctype = (ClassType) cexp.getClassType();
- // If ctype is a class that hasn't been compiled yet (and
- // ClassExp#declareParts hasn't been called yet)
- // then we may may get a tentative Field created
- // by ClassExp#createFields.
- // BUG: This doesn't work for not-yet compiled methods.
- Member part = SlotGet.lookupMember(ctype, dname, ctype);
- boolean contextStatic
- = (caller == cexp.clinitMethod
- || (caller != cexp.initMethod
- && caller.nameDecl.isStatic()));
- if (part == null) {
- PrimProcedure[] methods
- = ClassMethods.getMethods(ctype, dname,
- contextStatic ? 'S' : 'V',
- ctype, language);
- if (methods.length == 0)
- continue;
- } else if (decl != null && ! dname.equals(part.getName())) {
- continue;
- }
- Expression part1;
- // FIXME We're throwing away 'part', which is wasteful.
- if (contextStatic)
- part1 = new ReferenceExp(((ClassExp) caller.getOuter()).nameDecl);
- else
- part1 = new ThisExp(caller.firstDecl());
- return CompileNamedPart.makeExp(part1,
- QuoteExp.getInstance(dname));
- }
- }
- Object nameToLookup;
- if (decl != null) {
- nameToLookup = decl.getSymbol();
- exp = null;
- ReferenceExp rexp = getOriginalRef(decl);
- if (rexp != null) {
- decl = rexp.getBinding();
- if (decl == null) {
- exp = rexp.getSymbol();
- nameToLookup = exp;
- }
- }
- } else {
- nameToLookup = exp;
- }
- Symbol symbol = (Symbol) exp;
- if (decl != null) {
- if (current_scope instanceof TemplateScope && decl.needsContext())
- cdecl = ((TemplateScope) current_scope).macroContext;
- else if (decl.getFlag(Declaration.FIELD_OR_METHOD)
- && ! decl.isStatic()) {
- scope = currentScope();
- for (;;) {
- if (scope == null)
- throw new Error("internal error: missing "+decl);
- if (scope.getOuter() == decl.context) // I.e. same class.
- break;
- scope = scope.getOuter();
- }
- cdecl = scope.firstDecl();
- }
- } else {
- Location loc
- = env.lookup(symbol,
- function && separate ? EnvironmentKey.FUNCTION
- : null);
- if (loc != null)
- loc = loc.getBase();
- if (loc instanceof FieldLocation) {
- FieldLocation floc = (FieldLocation) loc;
- try {
- decl = floc.getDeclaration();
- if (! inlineOk(null)
- // A kludge - we get a bunch of testsuite failures
- // if we don't inline $lookup$. FIXME.
- && (decl != getNamedPartDecl
- // Another kludge to support "object" as a
- // type specifier.
- && ! isObjectSyntax(floc.getDeclaringClass(),
- floc.getMemberName())))
- decl = null;
- else if (immediate) {
- if (! decl.isStatic()) {
- cdecl = new Declaration("(module-instance)");
- cdecl.setValue(new QuoteExp(floc.getInstance()));
- }
- } else if (decl.isStatic()) {
- // If the class has been loaded through ZipLoader
- // or ArrayClassLoader then it might not be visible
- // if loaded through some other ClassLoader.
- Class fclass = floc.getRClass();
- ClassLoader floader;
- if (fclass == null
- || ((floader = fclass.getClassLoader())
- instanceof ZipLoader)
- || floader instanceof ArrayClassLoader)
- decl = null;
- } else
- decl = null;
- } catch (Exception ex) {
- error('e',
- "exception loading '" + exp
- + "' - " + ex.getMessage());
- decl = null;
- }
- }
- else if (mode != 'M' && (loc == null || ! loc.isBound()))
- {
- Expression e = checkDefaultBinding(symbol, this);
- if (e != null)
- return e;
- }
- /*
- else if (Compilation.inlineOk && function) {
- // Questionable. fail with new set_b implementation,
- // which just call rewrite_car on the lhs,
- // if we don't require function to be true. FIXME.
- decl = Declaration.getDeclaration(proc);
- }
- */
- }
- if (decl != null) {
- // A special kludge to deal with the overloading between the
- // object macro and object as being equivalent to java.lang.Object.
- // A cleaner solution would be to use an identifier macro.
- Field dfield = decl.getField();
- if (! function && dfield != null
- && isObjectSyntax(dfield.getDeclaringClass(),
- dfield.getName()))
- return QuoteExp.getInstance(Object.class);
- if (decl.getContext() instanceof PatternScope)
- return syntaxError("reference to pattern variable "+decl.getName()+" outside syntax template");
- }
- if (decl == null && function
- && nameToLookup==LispLanguage.lookup_sym)
- decl = getNamedPartDecl;
- int scanNesting = decl == null ? 0
- : Declaration.followAliases(decl).getScanNesting();
- if (scanNesting > 0) {
- if (scanNesting > curScanNesting())
- error('e', "using repeat variable '"+decl.getName()+"' while not in repeat context");
- else {
- return new ReferenceExp
- (scanContextStack.get(scanNesting-1).addSeqDecl(decl));
- }
- }
- ReferenceExp rexp = new ReferenceExp (nameToLookup, decl);
- rexp.setContextDecl(cdecl);
- rexp.setLine(this);
- if (function && separate)
- rexp.setFlag(ReferenceExp.PREFER_BINDING2);
- return rexp;
- } else if (exp instanceof LangExp)
- return rewrite(((LangExp) exp).getLangValue(), function);
- else if (exp instanceof Expression)
- return (Expression) exp;
- else if (exp == Special.abstractSpecial)
- return QuoteExp.abstractExp;
- else if (exp == Boolean.TRUE)
- return QuoteExp.trueExp;
- else if (exp == Boolean.FALSE)
- return QuoteExp.falseExp;
- else if (exp == Special.nativeSpecial)
- return QuoteExp.nativeExp;
- else {
- if (exp instanceof Keyword && ! keywordsAreSelfEvaluating())
- error('w', "keyword should be quoted if not in argument position");
- if (exp instanceof String)
- exp = new IString((String) exp);
- return QuoteExp.getInstance(Quote.quote(exp, this), this);
- }
- }
- /**
- * If a symbol is lexically unbound, look for a default binding.
- * The default implementation does the following:
- *
- * If the symbol is the name of an existing Java class, return that class.
- * Handles both with and without (semi-deprecated) angle-brackets:
- * {@code <java.lang.Integer>} and {@code java.lang.Integer}.
- * Also handles arrays, such as {@code java.lang.String[]}.
- *
- * If the symbol starts with {@code '@'} parse as an annotation class.
- *
- * Recognizes quanties with units, such as {@code 2m} and {@code 3m/s^2}.
- *
- * Handles the xml and unit namespaces.
- *
- * @return null if no binding, otherwise an Expression.
- *
- * FIXME: This method should be refactored. The quantities parsing should
- * be moved to its own method at least.
- */
- public Expression checkDefaultBinding(Symbol symbol, Translator tr) {
- Namespace namespace = symbol.getNamespace();
- String local = symbol.getLocalPart();
- String name = symbol.toString();
- int len = name.length();
- if (namespace instanceof XmlNamespace)
- return makeQuoteExp(((XmlNamespace) namespace).get(local));
- String namespaceName = namespace.getName();
- if (namespaceName == LispLanguage.unitNamespace.getName()) {
- Object val = Unit.lookup(local);
- if (val != null)
- return makeQuoteExp(val);
- }
- if (namespaceName == LispLanguage.entityNamespace.getName()) {
- Object val = lookupStandardEntity(local);
- if (val == null) {
- tr.error('e', "unknown entity name "+local);
- val = "{"+namespace.getPrefix()+":"+local+"}";
- }
- return makeQuoteExp(val);
- }
- char ch0 = name.charAt(0);
- if (ch0 == '@') { // Deprecated - reader now returns ($splice$ ATYPE).
- String rest = name.substring(1);
- Expression classRef = tr.rewrite(Symbol.valueOf(rest));
- return MakeAnnotation.makeAnnotationMaker(classRef);
- }
- // Look for quantities.
- if (ch0 == '-' || ch0 == '+' || Character.digit(ch0, 10) >= 0) {
- // 1: initial + or -1 seen.
- // 2: digits seen
- // 3: '.' seen
- // 4: fraction seen
- // 5: [eE][=+]?[0-9]+ seen
- int state = 0;
- int i = 0;
-
- for (; i < len; i++) {
- char ch = name.charAt(i);
- if (Character.digit(ch, 10) >= 0)
- state = state < 3 ? 2 : state < 5 ? 4 : 5;
- else if ((ch == '+' || ch == '-') && state == 0)
- state = 1;
- else if (ch == '.' && state < 3)
- state = 3;
- else if ((ch == 'e' || ch == 'E') && (state == 2 || state == 4)
- && i + 1 < len) {
- int j = i + 1;
- char next = name.charAt(j);
- if ((next == '-' || next == '+') && ++j < len)
- next = name.charAt(j);
- if (Character.digit(next, 10) < 0)
- break;
- state = 5;
- i = j + 1;
- }
- else
- break;
- }
- tryQuantity:
- if (i < len && state > 1) {
- DFloNum num = new DFloNum(name.substring(0, i));
- boolean div = false;
- ArrayList vec = new ArrayList();
- for (; i < len;) {
- char ch = name.charAt(i++);
- if (ch == '*') {
- if (i == len)
- break tryQuantity;
- ch = name.charAt(i++);
- } else if (ch == '/') {
- if (i == len || div)
- break tryQuantity;
- div = true;
- ch = name.charAt(i++);
- }
- int unitStart = i - 1;
- int unitEnd;
- for (;;) {
- if (!Character.isLetter(ch)) {
- unitEnd = i - 1;
- if (unitEnd == unitStart)
- break tryQuantity;
- break;
- }
- if (i == len) {
- unitEnd = i;
- ch = '1';
- break;
- }
- ch = name.charAt(i++);
- }
- vec.add(name.substring(unitStart, unitEnd));
- boolean expRequired = false;
- if (ch == '^') {
- expRequired = true;
- if (i == len)
- break tryQuantity;
- ch = name.charAt(i++);
- }
- boolean neg = div;
- if (ch == '+') {
- expRequired = true;
- if (i == len)
- break tryQuantity;
- ch = name.charAt(i++);
- } else if (ch == '-') {
- expRequired = true;
- if (i == len)
- break tryQuantity;
- ch = name.charAt(i++);
- neg = !neg;
- }
- int nexp = 0;
- int exp = 0;
- for (;;) {
- int dig = Character.digit(ch, 10);
- if (dig <= 0) {
- i--;
- break;
- }
- exp = 10 * exp + dig;
- nexp++;
- if (i == len)
- break;
- ch = name.charAt(i++);
- }
- if (nexp == 0) {
- exp = 1;
- if (expRequired)
- break tryQuantity;
- }
- if (neg)
- exp = -exp;
- vec.add(IntNum.make(exp));
- }
- if (i == len) {
- int nunits = vec.size() >> 1;
- Expression[] units = new Expression[nunits];
- for (i = 0; i < nunits; i++) {
- String uname = (String) vec.get(2 * i);
- Symbol usym = LispLanguage.unitNamespace.getSymbol(uname.intern());
- Expression uref = tr.rewrite(usym);
- IntNum uexp = (IntNum) vec.get(2 * i + 1);
- if (uexp.longValue() != 1)
- uref = new ApplyExp(Expt.expt,
- new Expression[] {
- uref, makeQuoteExp(uexp)
- });
- units[i] = uref;
- }
- Expression unit;
- if (nunits == 1)
- unit = units[0];
- else
- unit = new ApplyExp(MultiplyOp.TIMES, units);
- return new ApplyExp(MultiplyOp.TIMES,
- new Expression[] {
- makeQuoteExp(num),
- unit
- });
- }
- }
- }
- boolean sawAngle;
- if (len > 2 && ch0 == '<' && name.charAt(len - 1) == '>') {
- name = name.substring(1, len - 1);
- len -= 2;
- sawAngle = true;
- } else
- sawAngle = false;
- int rank = 0;
- while (len > 2 && name.charAt(len - 2) == '['
- && name.charAt(len - 1) == ']') {
- len -= 2;
- rank++;
- }
- //(future) String cname = (namespace == LispPackage.ClassNamespace) ? local : name;
- String cname = name;
- if (rank != 0)
- cname = name.substring(0, len);
- try {
- Type type = getLanguage().getNamedType(cname);
- if (rank > 0 && (!sawAngle || type == null)) {
- Symbol tsymbol = namespace.getSymbol(cname.intern());
- Expression texp = tr.rewrite(tsymbol, false);
- texp = InlineCalls.inlineCalls(texp, tr);
- if (!(texp instanceof ErrorExp))
- type = tr.getLanguage().getTypeFor(texp);
- }
- if (type != null) {
- // Somewhat inconsistent: Types named by getNamedType are Type,
- // while standard type/classes are Class. FIXME.
- while (--rank >= 0) {
- type = gnu.bytecode.ArrayType.make(type);
- }
- return makeQuoteExp(type);
- }
- Class clas;
- type = Type.lookupType(cname);
- if (type instanceof gnu.bytecode.PrimType)
- clas = type.getReflectClass();
- else {
- if (cname.indexOf('.') < 0)
- cname = (tr.classPrefix
- + Mangling.mangleNameIfNeeded(cname));
- if (rank == 0) {
- ModuleManager mmanager = ModuleManager.getInstance();
- ModuleInfo typeInfo = mmanager.searchWithClassName(cname);
- if (typeInfo != null) {
- Compilation tcomp = typeInfo.getCompilation();
- if (tcomp != null && tcomp.mainClass != null) {
- QuoteExp qexp = new QuoteExp(tcomp.mainClass,
- Type.javalangClassType);
- qexp.setLocation(this);
- return qexp;
- }
- }
- }
- clas = ClassType.getContextClass(cname);
- }
- if (clas != null) {
- if (rank > 0) {
- type = Type.make(clas);
- while (--rank >= 0) {
- type = gnu.bytecode.ArrayType.make(type);
- }
- clas = type.getReflectClass();
- }
- return makeQuoteExp(clas);
- }
- } catch (ClassNotFoundException ex) {
- Package pack = gnu.bytecode.ArrayClassLoader.getContextPackage(name);
- if (pack != null)
- return makeQuoteExp(pack);
- } catch (NoClassDefFoundError ex) {
- tr.error('w', "error loading class " + cname + " - " + ex.getMessage() + " not found");
- } catch (Exception ex) {
- }
- if (name.startsWith("array")) {
- Type atype = LispLanguage.decodeArrayType(name);
- if (atype != null)
- return makeQuoteExp(atype);
- }
- return null;
- }
- static Map<String,String> standardEntities;
- public static synchronized String lookupStandardEntity(String key) {
- if (standardEntities == null) {
- standardEntities = new HashMap<String,String>();
- Char.addNamedChars(standardEntities);
- }
- String val = standardEntities.get(key);
- if (val != null)
- return val;
- return val = StandardNamedChars.instance.get(key);
- }
- public static void setLine(Expression exp, Object location)
- {
- if (location instanceof SourceLocator)
- exp.setLocation((SourceLocator) location);
- }
- public static void setLine(Declaration decl, Object location)
- {
- if (location instanceof SourceLocator)
- decl.setLocation((SourceLocator) location);
- }
- PairWithPosition positionPair;
- /*
- public Object pushPositionOfCar(Object pair)
- {
- if (pair instanceof Pair)
- {
- Object car = ((Pair) pair).getCar();
- if (car instanceof PairWithPosition)
- pair = car;
- }
- return pushPositionOf(pair);
- }*/
- /** Note current line number position from a PairWithPosition.
- * Return an object to pass to popPositionOf.
- */
- public Object pushPositionOf(Object pos)
- {
- if (pos instanceof SyntaxForm)
- pos = ((SyntaxForm) pos).getDatum();
- PairWithPosition pair;
- if (pos instanceof PairWithPosition)
- pair = (PairWithPosition) pos;
- else if (pos instanceof SourceLocator)
- pair = new PairWithPosition((SourceLocator) pos, null, null);
- else
- return null;
- Object saved;
- if (positionPair == null
- || positionPair.getFileName() != getFileName()
- || positionPair.getLineNumber() != getLineNumber()
- || positionPair.getColumnNumber() != getColumnNumber())
- {
- saved = new PairWithPosition(this, this, positionPair);
- }
- else
- saved = positionPair;
- setLine(pos);
- positionPair = pair;
- return saved;
- }
- /** Restore line number position from a previous pushPositionOf.
- * @param saved value returned by matching pushPositionOf.
- */
- public void popPositionOf(Object saved)
- {
- if (saved == null)
- return;
- setLine(saved);
- positionPair = (PairWithPosition) saved;
- if (positionPair.getCar() == this)
- positionPair = (PairWithPosition) positionPair.getCdr();
- }
- public void errorWithPosition(String message, Object form) {
- Object save = pushPositionOf(form);
- error('e', message);
- popPositionOf(save);
- }
- public void errorIfNonEmpty(Object form) {
- if (form != LList.Empty)
- error('e', "invalid improper (dotted) list");
- }
- /** Set the line position of the argument to the current position. */
- public void setLineOf (Expression exp)
- {
- // "Special" QuoteExps may be shared, but the position gets set (in the
- // call to QuoteExp.getInstance at end of re-write) for normal ones.
- if (exp instanceof QuoteExp)
- return;
- if (exp.getLineNumber() <= 0)
- exp.setLocation(this);
- }
- /** Extract a type from the car of a pair. */
- public Type exp2Type(Pair typeSpecPair)
- {
- return exp2Type(typeSpecPair, null, null);
- }
- public Type exp2Type(Pair typeSpecPair, Declaration decl, SyntaxForm syntax)
- {
- Object saved = pushPositionOf(typeSpecPair);
- try
- {
- Expression texp = rewrite_car(typeSpecPair, syntax);
- if (texp instanceof ErrorExp)
- return null;
- Type type = getLanguage().getTypeFor(texp);
- if (type == null)
- {
- try
- {
- Object t = texp.eval(env);
- if (t instanceof Class)
- type = Type.make((Class) t);
- else if (t instanceof Type)
- type = (Type) t;
- }
- catch (Error ex)
- {
- throw ex;
- }
- catch (Throwable ex)
- {
- }
- }
- if (type == null)
- {
- if (texp instanceof ReferenceExp)
- error('e', "unknown type name '"
- + ((ReferenceExp) texp).getName() + '\'');
- else
- error('e',
- "invalid type spec");
- type = Type.errorType;
- }
- if (decl != null)
- decl.setType(texp, type);
- return type;
- }
- finally
- {
- popPositionOf(saved);
- }
- }
- public Expression rewrite_with_position (Object exp, boolean function,
- PairWithPosition pair)
- {
- Object saved = pushPositionOf(pair);
- Expression result;
- try
- {
- if (exp == pair)
- result = rewrite_pair(pair, function); // To avoid a cycle
- else
- result = rewrite (exp, function);
- setLineOf(result);
- }
- finally
- {
- popPositionOf(saved);
- }
- return result;
- }
- public static Object wrapSyntax (Object form, SyntaxForm syntax)
- {
- if (syntax == null || form instanceof Expression)
- return form;
- else
- return SyntaxForms.fromDatumIfNeeded(form, syntax);
- }
- /** Pop from formStack all forms that come after beforeFirst.
- */
- public Values popForms(Pair beforeFirst)
- {
- Object tail = formStack.popTail(beforeFirst);
- if (tail == LList.Empty)
- return Values.empty;
- return new ValuesFromLList((LList) tail);
- }
- public void scanForm (Object st, ScopeExp defs)
- {
- if (st instanceof SyntaxForm)
- {
- SyntaxForm sf = (SyntaxForm) st;
- ScopeExp save_scope = setPushCurrentScope(sf.getScope());
- try
- {
- Pair beforeFirst = formStack.last;
- scanForm(sf.getDatum(), defs);
- pushForm(wrapSyntax(popForms(beforeFirst), sf));
- return;
- }
- finally
- {
- setPopCurrentScope(save_scope);
- }
- }
- if (st instanceof Values)
- {
- if (st == Values.empty)
- st = QuoteExp.voidExp; // From #!void
- else if (st instanceof ValuesFromLList)
- {
- for (Object vs = ((ValuesFromLList) st).values;
- vs != LList.Empty; )
- {
- Pair p = (Pair) vs;
- Object save = pushPositionOf(p);
- scanForm(p.getCar(), defs);
- popPositionOf(save);
- vs = p.getCdr();
- }
- }
- else
- {
- Object[] vals = ((Values) st).getValues();
- for (int i = 0; i < vals.length; i++)
- scanForm(vals[i], defs);
- return;
- }
- }
- if (st instanceof Pair)
- {
- Pair st_pair = (Pair) st;
- Declaration saveContext = macroContext;
- Syntax syntax = null;
- ScopeExp savedScope = current_scope;
- Object savedPosition = pushPositionOf(st);
- if (st instanceof SourceLocator && defs.getLineNumber() < 0)
- defs.setLocation((SourceLocator) st);
- try
- {
- Object obj = st_pair.getCar();
- if (obj instanceof SyntaxForm)
- {
- SyntaxForm sf = (SyntaxForm) st_pair.getCar();
- savedScope = setPushCurrentScope(sf.getScope());
- obj = sf.getDatum();
- }
- Pair p;
- if (obj instanceof Pair
- && (p = (Pair) obj).getCar() == LispLanguage.lookup_sym
- && p.getCdr() instanceof Pair
- && (p = (Pair) p.getCdr()).getCdr() instanceof Pair)
- {
- Expression part1 = rewrite(p.getCar());
- Expression part2 = rewrite_car_for_lookup((Pair) p.getCdr());
- Object value1 = part1.valueIfConstant();
- Object value2 = part2.valueIfConstant();
- if (value1 instanceof Class && value2 instanceof Symbol)
- {
- try
- {
- obj = GetNamedPart.getNamedPart(value1, (Symbol)value2);
- if (obj instanceof Syntax)
- syntax = (Syntax) obj;
- }
- catch (Exception ex)
- {
- obj = null;
- }
- }
- else
- obj = namespaceResolve(part1, part2);
- }
- if (obj instanceof Symbol && ! selfEvaluatingSymbol(obj))
- {
- Expression func = rewrite(obj, 'M');
- if (func instanceof ReferenceExp)
- {
- Declaration decl = ((ReferenceExp) func).getBinding();
- if (decl != null)
- syntax = check_if_Syntax(decl);
- else
- {
- obj = resolve(obj, true);
- if (obj instanceof Syntax)
- syntax = (Syntax) obj;
- }
- }
- }
- // Recognize deferred begin created in scanBody for pendingForms.
- // A seemingly-cleaner (obj instanceof Syntax) causes problems
- // with some Syntax forms, such as define.
- else if (obj == kawa.standard.begin.begin
- || obj == kawa.standard.define_library.define_library_scan)
- syntax = (Syntax) obj;
- }
- finally
- {
- if (savedScope != current_scope)
- setPopCurrentScope(savedScope);
- popPositionOf(savedPosition);
- }
- if (syntax != null)
- {
- String save_filename = getFileName();
- try
- {
- syntax.scanForm(st_pair, defs, this);
- return;
- }
- finally
- {
- macroContext = saveContext;
- }
- }
- }
- pushForm(st);
- }
- /** Recursive helper method for rewrite_body.
- * Scan body for definitions, adding partially macro-expanded
- * expressions into the <code>formStack</code>.
- * @param makeList if true, return a list representation of the scanned
- * forms (not including declarations); else forms are push on formStack
- * @return a list of forms if <code>makeList</code> (possibly wrapped
- * in a <code>SyntaxForm</code>); otherwise <code>null</code>.
- */
- public LList scanBody (Object body, ScopeExp defs, boolean makeList)
- {
- LList list = makeList ? LList.Empty : null;
- Pair lastPair = null;
- while (body != LList.Empty)
- {
- if (body instanceof SyntaxForm)
- {
- SyntaxForm sf = (SyntaxForm) body;
- ScopeExp save_scope = setPushCurrentScope(sf.getScope());
- try
- {
- Pair first = formStack.last;
- LList f = scanBody(sf.getDatum(), defs, makeList);
- if (makeList)
- {
- f = (LList) SyntaxForms.fromDatumIfNeeded(f, sf);
- if (lastPair == null)
- return f;
- lastPair.setCdrBackdoor(f);
- return list;
- }
- pushForm(wrapSyntax(popForms(first), sf));
- return null;
- }
- finally
- {
- setPopCurrentScope(save_scope);
- }
- }
- else if (body instanceof Pair)
- {
- Pair pair = (Pair) body;
- Pair first = formStack.last;
- Object savePos = pushPositionOf(pair);
- scanForm(pair.getCar(), defs);
- popPositionOf(savePos);
- if (getState() == Compilation.PROLOG_PARSED && pendingForm != null)
- {
- // We've seen a require form during the initial pass when
- // we're looking module names. Defer the require and any
- // following forms in this body.
- if (pair.getCar() != pendingForm)
- pair = makePair(pair, pendingForm, pair.getCdr());
- pendingForm = new Pair(kawa.standard.begin.begin, pair);
- if (makeList)
- formStack.pushAll(list);
- return LList.Empty;
- }
- if (makeList)
- {
- Pair last = formStack.lastPair();
- LList nlist = (LList) formStack.popTail(first);
- if (lastPair == null)
- list = nlist;
- else
- lastPair.setCdrBackdoor(nlist);
- if (last != first)
- lastPair = last;
- }
- body = pair.getCdr();
- }
- else
- {
- pushForm(syntaxError("body is not a proper list"));
- break;
- }
- }
- return list;
- }
- public static Pair makePair(Pair pair, Object car, Object cdr)
- {
- if (pair instanceof PairWithPosition)
- return new PairWithPosition((PairWithPosition) pair, car, cdr);
- return new Pair(car, cdr);
- }
- /**
- * Re-write a Scheme 'body' in S-expression format into internal form.
- */
- public Expression rewrite_body (Object exp)
- {
- // NOTE we have both a rewrite_body and a rewriteBody.
- // This is confusing, at the least. FIXME.
- Object saved = pushPositionOf(exp);
- LetExp defs = new LetExp();
- defs.setFlag(LetExp.IS_BODY_SCOPE);
- int renamedAliasOldSize = renamedAliasCount();
- Pair first = formStack.last;
- defs.setOuter(current_scope);
- current_scope = defs;
- try
- {
- LList list = scanBody(exp, defs, true);
- if (list.isEmpty())
- pushForm(syntaxError("body with no expressions"));
- int ndecls = 0;
- for (Declaration decl = defs.firstDecl(); decl != null; decl = decl.nextDecl())
- {
- if (! decl.getFlag(Declaration.IS_DYNAMIC))
- {
- ndecls++;
- decl.setInitValue(QuoteExp.undefined_exp);
- }
- }
- rewriteBody(list);
- int renamedAliasNewSize = renamedAliasCount();
- popRenamedAlias(renamedAliasNewSize - renamedAliasOldSize);
- Expression body = makeBody(first, null);
- setLineOf(body);
- if (ndecls == 0)
- return body;
- defs.setBody(body);
- setLineOf(defs);
- return defs;
- }
- finally
- {
- pop(defs);
- popPositionOf(saved);
- }
- }
-
- protected void rewriteBody (LList forms)
- {
- while (forms != LList.Empty)
- {
- Pair pair = (Pair) forms;
- Object saved = pushPositionOf(pair);
- try
- {
- rewriteInBody(pair.getCar());
- }
- finally
- {
- popPositionOf(saved);
- }
- forms = (LList) pair.getCdr();
- }
- }
- /** Combine a list of zero or more expression forms into a "body". */
- protected Expression makeBody(Pair head, ScopeExp scope)
- {
- Object tail = formStack.popTail(head);
- int nforms = LList.length(tail);
- if (nforms == 0)
- return QuoteExp.voidExp;
- Pair first = (Pair) tail;
- if (nforms == 1)
- {
- return (Expression) first.getCar();
- }
- else
- {
- Expression[] exps = new Expression[nforms];
- first.toArray(exps);
- if (scope instanceof ModuleExp)
- return new ApplyExp(gnu.kawa.functions.AppendValues.appendValues,
- exps);
- else
- return makeBody(exps);
- }
- }
- public boolean appendBodyValues () { return false; }
- /** Combine a 'body' consisting of a list of expression. */
- public Expression makeBody(Expression[] exps)
- {
- if (appendBodyValues())
- return new ApplyExp(gnu.kawa.functions.AppendValues.appendValues, exps);
- else
- return new BeginExp (exps);
- }
- /** Storage used by noteAccess and processAccesses. */
- ArrayList notedAccess;
- /** Note that we reference name in a given scope.
- * This may be called when defining a macro, at scan-time,
- * and the name may be bound to a declaration we haven't seen yet. */
- public void noteAccess (Object name, ScopeExp scope)
- {
- if (notedAccess == null)
- notedAccess = new ArrayList();
- notedAccess.add(name);
- notedAccess.add(scope);
- }
- /** Check references recorded by noteAccess.
- * Resolve now to a Declaration, and note the access.
- * This is needed in case an exported macro references a private Declaration.
- */
- public void processAccesses ()
- {
- if (notedAccess == null)
- return;
- int sz = notedAccess.size();
- ScopeExp saveScope = current_scope;
- for (int i = 0; i < sz; i += 2)
- {
- Object name = notedAccess.get(i);
- ScopeExp scope = (ScopeExp) notedAccess.get(i+1);
- if (current_scope != scope)
- {
- // I.e. first time do equivalent of setPushCurrentScope
- if (current_scope == saveScope)
- lexical.pushSaveTopLevelRedefs();
- setCurrentScope(scope);
- }
- Declaration decl = (Declaration) lexical.lookup(name, -1);
- if (decl != null && ! decl.getFlag(Declaration.IS_UNKNOWN))
- {
- decl.getContext().currentLambda().capture(decl);
- decl.setCanRead(true);
- decl.setSimple(false);
- decl.setFlag(Declaration.EXTERNAL_ACCESS);
- }
- }
- if (current_scope != saveScope)
- setPopCurrentScope(saveScope);
- }
- public void finishModule(ModuleExp mexp)
- {
- boolean moduleStatic = mexp.isStatic();
- for (Declaration decl = mexp.firstDecl();
- decl != null; decl = decl.nextDecl())
- {
- if (decl.getFlag(Declaration.NOT_DEFINING))
- {
- String msg1 = "'";
- String msg2
- = (decl.getFlag(Declaration.EXPORT_SPECIFIED)
- ? "' exported but never defined"
- : decl.getFlag(Declaration.STATIC_SPECIFIED)
- ? "' declared static but never defined"
- : "' declared but never defined");
- error('e', decl, msg1, msg2);
- }
- if (mexp.getFlag(ModuleExp.EXPORT_SPECIFIED)
- || (generateMainMethod() && ! immediate))
- {
- if (decl.getFlag(Declaration.EXPORT_SPECIFIED))
- {
- if (decl.isPrivate())
- {
- if (decl.getFlag(Declaration.PRIVATE_SPECIFIED))
- error('e', decl,
- "'", "' is declared both private and exported");
- decl.setPrivate(false);
- }
- }
- else if (! kawa.standard.IfFeature.isProvide(decl))
- decl.setPrivate(true);
- }
- if (moduleStatic)
- decl.setFlag(Declaration.STATIC_SPECIFIED);
- else if ((mexp.getFlag(ModuleExp.NONSTATIC_SPECIFIED)
- && ! decl.getFlag(Declaration.STATIC_SPECIFIED))
- || gnu.expr.Compilation.moduleStatic < 0
- || mexp.getFlag(ModuleExp.SUPERTYPE_SPECIFIED))
- decl.setFlag(Declaration.NONSTATIC_SPECIFIED);
- }
- if (mexp.getFlag(ModuleExp.SUPERTYPE_SPECIFIED))
- mexp.setFlag(false, ModuleExp.USE_DEFINED_CLASS);
- }
- public void resolveModule(ModuleExp mexp)
- {
- Expression savePos = new ReferenceExp((Object) null);
- int numPending = pendingImports == null ? 0 : pendingImports.size();
- for (int i = 0; i < numPending; )
- {
- ModuleInfo info = (ModuleInfo) pendingImports.elementAt(i++);
- ScopeExp defs = (ScopeExp) pendingImports.elementAt(i++);
- Expression posExp = (Expression) pendingImports.elementAt(i++);
- Pair beforeGoal = (Pair) pendingImports.elementAt(i++);
- DeclSetMapper mapper = (DeclSetMapper) pendingImports.elementAt(i++);
- if (mexp == defs)
- {
- // process(BODY_PARSED);
- savePos.setLine(this);
- setLine(posExp);
- Pair beforeImports = formStack.last;
- kawa.standard.require.importDefinitions(null, info, mapper,
- formStack, defs, this);
- if (beforeGoal != beforeImports
- && beforeImports != formStack.last)
- {
- // Move forms derived from the import forwards in the list,
- // just following beforeGoal.
- Object firstGoal = beforeGoal.getCdr();
- Object firstImports = beforeImports.getCdr();
- beforeGoal.setCdrBackdoor(firstImports);
- formStack.last.setCdrBackdoor(firstGoal);
- beforeImports.setCdrBackdoor(LList.Empty);
- formStack.last = beforeImports;
- }
- setLine(savePos);
- }
- }
- pendingImports = null;
- setModule(mexp);
- savePos.setLine(this);
- setLine(null, -1, -1);
- Compilation save_comp = Compilation.setSaveCurrent(this);
- try
- {
- Pair firstForm = formStack.getHead();
- rewriteBody((LList) formStack.popTail(firstForm));
- mexp.body = makeBody(firstForm, mexp);
- processAccesses();
- // In immediate mode need to preserve Declaration for current "session".
- if (! immediate)
- lexical.pop(mexp);
- // Patch up renamed exports - see export.
- for (Declaration decl = mexp.firstDecl(); decl != null;
- decl = decl.nextDecl()) {
- if (decl.getSymbol() == null
- && decl.getFlag(Declaration.EXPORT_SPECIFIED)) {
- decl.patchSymbolFromSet();
- }
- }
- }
- finally
- {
- Compilation.restoreCurrent(save_comp);
- setLine(savePos);
- }
- /* DEBUGGING:
- OutPort err = OutPort.errDefault ();
- err.print ("[Re-written expression for load/compile: ");
- mexp.print (err);
- //err.print ("\nbefore load<"+mod.getClass().getName()+">");
- err.println();
- err.flush();
- */
- }
- public Declaration makeRenamedAlias (Declaration decl,
- ScopeExp templateScope)
- {
- if (templateScope == null)
- return decl; // ???
- return makeRenamedAlias(decl.getSymbol(), decl, templateScope);
- }
- public Declaration makeRenamedAlias (Object name,
- Declaration decl,
- ScopeExp templateScope)
- {
- Declaration alias = new Declaration(name);
- alias.setAlias(true);
- alias.setPrivate(true);
- alias.context = templateScope;
- ReferenceExp ref = new ReferenceExp(decl);
- ref.setDontDereference(true);
- alias.noteValue(ref);
- return alias;
- }
- /** Push an alias for a declaration in a scope.
- * If the name of {@code decl} came from a syntax template
- * whose immediate scope is {@code templateScope},
- * then the same syntax template may contain local variable references
- * that are also in the same {@code templateScope}.
- * Such variable references will <em>not</em> look in the current
- * "physical" scope, where we just created {@code decl}, but
- * will instead search the "lexical" {@code templateScope}.
- * So that such references can resolve to {@code decl}, we
- * create an alias in {@code templateScope} that points
- * to {@code decl}. We record that we did this in the
- * {@code renamedAliasStack}, so we can remove the alias later.
- */
- public void pushRenamedAlias (Declaration alias)
- {
- Declaration decl = getOriginalRef(alias).getBinding();
- ScopeExp templateScope = alias.context;
- decl.setSymbol(null);
- Declaration old = templateScope.lookup(alias.getSymbol());
- if (old != null)
- templateScope.remove(old);
- templateScope.addDeclaration(alias);
- if (renamedAliasStack == null)
- renamedAliasStack = new Stack<Declaration>();
- renamedAliasStack.push(old);
- renamedAliasStack.push(alias);
- }
- public int renamedAliasCount() {
- return renamedAliasStack == null ? 0 : renamedAliasStack.size() >> 1;
- }
- /** Remove one or more aliases created by <code>pushRenamedAlias</code>. */
- public void popRenamedAlias (int count)
- {
- while (--count >= 0)
- {
- Declaration alias = (Declaration) renamedAliasStack.pop();
- ScopeExp templateScope = alias.getContext();
- Declaration decl = getOriginalRef(alias).getBinding();
- decl.setSymbol(alias.getSymbol());
- templateScope.remove(alias);
- Declaration old = renamedAliasStack.pop();
- if (old != null)
- templateScope.addDeclaration(old);
- }
- }
- public Declaration define(Object name, ScopeExp defs) {
- return define(name, (TemplateScope) null, defs);
- }
- public Declaration define(Object name, SyntaxForm nameSyntax,
- ScopeExp defs) {
- return define(name, nameSyntax == null ? null : nameSyntax.getScope(),
- defs);
- }
- public Declaration define(Object name, TemplateScope templateScope,
- ScopeExp defs) {
- ScopeExp scope = templateScope != null ? templateScope
- : currentScope();
- boolean aliasNeeded = scope != defs;
- Object declName = aliasNeeded
- ? Symbol.makeUninterned(name.toString())
- : name;
- Declaration decl = defs.getDefine(declName, this);
- if (aliasNeeded) {
- Declaration alias = makeRenamedAlias(name, decl, scope);
- if (defs instanceof LetExp)
- pushRenamedAlias(alias);
- else
- scope.addDeclaration(alias);
- }
- push(decl);
- return decl;
- }
- static boolean isObjectSyntax (ClassType declaringClass, String fieldName)
- {
- return "objectSyntax".equals(fieldName)
- && "kawa.standard.object".equals(declaringClass.getName());
- }
- public FormStack formStack = new FormStack(this);
- public void pushForm(Object value) { formStack.push(value); }
-
- /** A list of "forms" to be further processed.
- * It is implemented as an LList so we can save position information.
- */
- public static class FormStack extends Pair {
- private Pair last = this;
- SourceLocator sloc;
-
- public FormStack(SourceLocator sloc) {
- this.sloc = sloc;
- this.cdr = LList.Empty;
- }
- /** Return the "head" of the list.
- * The cdr of the head is the first element.
- */
- public Pair getHead() { return this; }
- public Object getFirst() { return cdr; }
- /** The Pair whose car is the last form in the list.
- * If the list is empty, this returns the list head.
- */
- @Override
- public Pair lastPair() { return last; }
- /* DEBUGGING:
- public void dump() {
- int i=0;
- System.err.println("formStack len:"+LList.length(getFirst()));
- for(Object x = getFirst(); x instanceof Pair; i++) {
- Pair p = (Pair) x;
- //if (! (p.getCar() instanceof SetExp))
- System.err.println("- #"+i+": "+p.getCar());
- x = p.getCdr();
- }
- }
- */
- public Object popTail(Pair oldTail) {
- Object r = oldTail.getCdr();
- oldTail.setCdrBackdoor(LList.Empty);
- last = oldTail;
- return r;
- }
-
- public void push(Object value) {
- PairWithPosition pair = new PairWithPosition(sloc, value, LList.Empty);
- last.setCdrBackdoor(pair);
- last = pair;
- }
- public void pushAll(LList values) {
- if (values == LList.Empty)
- return;
- last.setCdrBackdoor(values);
- last = ((Pair) values).lastPair();
- }
-
- public void pushAll(LList values, Pair valuesLast) {
- if (values == LList.Empty)
- return;
- last.setCdrBackdoor(values);
- last = valuesLast;
- }
-
- public void pushAfter(Object value, Pair position) {
- Pair pair = new PairWithPosition(sloc, value, position.getCdr());
- position.setCdrBackdoor(pair);
- if (last == position)
- last = pair;
- }
- }
- /** An implementationof Values using a linked list.
- */
- public static class ValuesFromLList extends Values.FromList<Object> {
- public LList values;
- public ValuesFromLList(LList values) {
- super(values);
- this.values = values;
- }
- }
- Stack<ScanContext> scanContextStack = new Stack<ScanContext>();
- public ScanContext getScanContext() { return scanContextStack.peek(); }
- public int curScanNesting() { return scanContextStack.size(); }
- public Stack<ScanContext> getScanContextStack() { return scanContextStack; }
- public void pushScanContext (LambdaExp lambda) {
- ScanContext newContext = new ScanContext();
- newContext.lambda = lambda;
- scanContextStack.push(newContext);
- }
- public void popScanContext() {
- scanContextStack.pop();
- }
- public static class ScanContext {
- LinkedHashMap<Declaration,Declaration> decls
- = new LinkedHashMap<Declaration,Declaration>();
- ArrayList<Expression> scanExpressions = null;
- LambdaExp lambda;
- public LambdaExp getLambda() { return lambda; }
- public Declaration addSeqDecl(Declaration scanVar) {
- Declaration param = decls.get(scanVar);
- if (param == null) {
- param = lambda.addParameter(null);
- decls.put(scanVar, param);
- }
- return param;
- }
- public void addSeqExpression(Expression scanExp) {
- if (scanExpressions == null)
- scanExpressions = new ArrayList<Expression>();
- scanExpressions.add(scanExp);
- }
- }
- }
|