123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- package kawa.standard;
- import gnu.expr.*;
- import gnu.kawa.functions.Convert;
- import gnu.kawa.functions.Curry1;
- import gnu.kawa.functions.CurryExp;
- import gnu.mapping.*;
- import gnu.text.*;
- import kawa.lang.*;
- public class SchemeCompilation extends Translator
- {
- public SchemeCompilation(Language language, SourceMessages messages,
- NameLookup lexical, Environment env) {
- super(language, messages, lexical, env);
- }
- public SchemeCompilation(Language language, SourceMessages messages,
- NameLookup lexical) {
- super(language, messages, lexical);
- }
- public static final Declaration applyFieldDecl =
- Declaration.getDeclarationFromStatic("kawa.standard.Scheme", "applyToArgs");
- @Override
- public Expression applyFunction(Expression func) {
- if (func instanceof LambdaExp)
- return null;
- else
- return new ReferenceExp(applyFieldDecl);
- }
- @Override
- public boolean isApplyFunction (Expression exp)
- {
- return isSimpleApplyFunction(exp);
- }
- @Override
- public boolean isSimpleApplyFunction (Expression exp)
- {
- return exp instanceof ReferenceExp
- && ((ReferenceExp) exp).getBinding() == applyFieldDecl;
- }
- /** Should the values of body/block be appended as multiple values?
- * Otherwise, just return the result of the final expression.
- */
- @Override
- public boolean appendBodyValues ()
- {
- return ((Scheme) getLanguage()).appendBodyValues();
- }
- public static final Lambda lambda = new kawa.lang.Lambda();
- public static final Lambda mlambda = lambda;
- static {
- lambda.setKeywords(Special.optional, Special.rest, Special.key);
- }
- public static final kawa.repl repl = new kawa.repl(Scheme.instance);
- /** If a symbol is lexically unbound, look for a default binding.
- * Recognizes {@code typename?} as a type predicate,
- * {@code ->typename} as a conversion function,
- * plus whatever the overridden method handles.
- * @return null if no binding, otherwise an Expression.
- */
- @Override
- public Expression checkDefaultBinding(Symbol symbol, Translator tr) {
- Namespace namespace = symbol.getNamespace();
- String local = symbol.getLocalPart();
- String name = symbol.toString();
- int len = name.length();
- if (len == 0)
- return null;
- int llen = local.length();
- // Map 'TYPE?' to '(lambda (obj) (instance? obj TYPE))'.
- // FIXME - this should be done after/during InlineCalls,
- // so we only do this if TYPE is a Type or Class.
- if (len > 1 && llen > 1 && name.charAt(len-1) == '?') {
- String tlocal = local.substring(0, llen-1).intern();
- Symbol tsymbol = namespace.getSymbol(tlocal);
- Expression texp = tr.rewrite(tsymbol, false);
- if (texp instanceof ReferenceExp) {
- Declaration decl = ((ReferenceExp) texp).getBinding();
- if (decl == null || decl.getFlag(Declaration.IS_UNKNOWN))
- texp = null;
- }
- else if (! (texp instanceof QuoteExp))
- texp = null;
- if (texp != null) {
- LambdaExp lexp = new LambdaExp(1);
- lexp.setSymbol(symbol);
- Declaration param = lexp.addDeclaration((Object) null);
- param.setFlag(Declaration.IS_PARAMETER);
- param.noteValueUnknown();
- lexp.body = new ApplyExp(Scheme.instanceOf,
- new ReferenceExp(param), texp);
- return lexp;
- }
- }
- // Map '->TYPE' to '(lambda (obj) (as TYPE obj))'.
- // FIXME - this should be done after/during InlineCalls,
- // so we only do this if TYPE is a Type or Class.
- if (len > 2 && llen > 2
- && name.charAt(0) == '-' && name.charAt(1) == '>') {
- String tlocal = local.substring(2).intern();
- Symbol tsymbol = namespace.getSymbol(tlocal);
- Expression texp = tr.rewrite(tsymbol, false);
- if (texp instanceof ReferenceExp) {
- Declaration decl = ((ReferenceExp) texp).getBinding();
- if (decl == null || decl.getFlag(Declaration.IS_UNKNOWN))
- texp = null;
- }
- else if (! (texp instanceof QuoteExp))
- texp = null;
- if (texp != null)
- return new CurryExp(Curry1.makeConverter, Convert.cast, texp);
- }
- return super.checkDefaultBinding(symbol, tr);
- }
- }
|