public Expr Parse(ParserContext pcon, object form) { if (pcon.Rhc == RHC.Eval) { return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "throw__" + RT.nextID())); } if (RT.Length((ISeq)form) == 1) { return(new ThrowExpr()); } return(new ThrowExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), RT.second(form)))); }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; if (RT.Length(form) != 3) { throw new ParseException("Malformed assignment, expecting (set! target val)"); } Expr target = Compiler.Analyze(new ParserContext(RHC.Expression, true), RT.second(form)); if (!(target is AssignableExpr ae)) { throw new ParseException("Invalid assignment target"); } return(new AssignExpr(ae, Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.third(form)))); }
public Expr Parse(object frm) { ISeq form = (ISeq)frm; if (RT.Length(form) != 3) { throw new ArgumentException("Malformed assignment, expecting (set! target val)"); } Expr target = Compiler.GenerateAST(RT.second(form)); if (!(target is AssignableExpr)) { throw new ArgumentException("Invalid assignment target"); } return(new AssignExpr((AssignableExpr)target, Compiler.GenerateAST(RT.third(form)))); }
public Expr Parse(ParserContext pcon, object form) { if (pcon.Rhc == RHC.Eval) { return(Compiler.Analyze(pcon, RT.list(RT.list(Compiler.FnOnceSym, PersistentVector.EMPTY, form)), "throw__" + RT.nextID())); } if (RT.Length((ISeq)form) == 1) { return(new ThrowExpr()); } if (RT.count(form) > 2) { throw new InvalidOperationException("Too many arguments to throw, throw expects a single Exception instance"); } return(new ThrowExpr(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), RT.second(form)))); }
internal static List <HostArg> ParseArgs(ParserContext pcon, ISeq argSeq) { List <HostArg> args = new List <HostArg>(); for (ISeq s = argSeq; s != null; s = s.next()) { object arg = s.first(); HostArg.ParameterType paramType = HostArg.ParameterType.Standard; LocalBinding lb = null; ISeq argAsSeq = arg as ISeq; if (argAsSeq != null) { Symbol op = RT.first(argAsSeq) as Symbol; if (op != null && op.Equals(ByRefSym)) { if (RT.Length(argAsSeq) != 2) { throw new ArgumentException("Wrong number of arguments to {0}", op.Name); } object localArg = RT.second(argAsSeq); Symbol symLocalArg = localArg as Symbol; if (symLocalArg == null || (lb = Compiler.ReferenceLocal(symLocalArg)) == null) { throw new ArgumentException("Argument to {0} must be a local variable.", op.Name); } paramType = HostArg.ParameterType.ByRef; arg = localArg; } } Expr expr = Compiler.Analyze(pcon.EvalOrExpr(), arg); args.Add(new HostArg(paramType, expr, lb)); } return(args); }
public Expr Parse(ParserContext pcon, object form) { ISeq sform = (ISeq)form; // form is one of: // (. x fieldname-sym) // (. x 0-ary-method) // (. x propertyname-sym) // (. x methodname-sym args)+ // (. x (methodname-sym args?)) // (. x (generic-m if (RT.Length(sform) < 3) { throw new ParseException("Malformed member expression, expecting (. target member ... )"); } string source = (string)Compiler.SourceVar.deref(); IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); // Compiler.GetSourceSpanMap(form); Symbol tag = Compiler.TagOf(sform); // determine static or instance // static target must be symbol, either fully.qualified.Typename or Typename that has been imported Type t = HostExpr.MaybeType(RT.second(sform), false); // at this point, t will be non-null if static Expr instance = null; if (t == null) { instance = Compiler.Analyze(pcon.EvalOrExpr(), RT.second(sform)); } bool isZeroArityCall = RT.Length(sform) == 3 && RT.third(sform) is Symbol; if (isZeroArityCall) { PropertyInfo pinfo = null; FieldInfo finfo = null; // TODO: Figure out if we want to handle the -propname otherwise. bool isPropName = false; Symbol sym = (Symbol)RT.third(sform); if (sym.Name[0] == '-') { isPropName = true; sym = Symbol.intern(sym.Name.Substring(1)); } string fieldName = Compiler.munge(sym.Name); // The JVM version does not have to worry about Properties. It captures 0-arity methods under fields. // We have to put in special checks here for this. // Also, when reflection is required, we have to capture 0-arity methods under the calls that // are generated by StaticFieldExpr and InstanceFieldExpr. if (t != null) { if ((finfo = Reflector.GetField(t, fieldName, true)) != null) { return(new StaticFieldExpr(source, spanMap, tag, t, fieldName, finfo)); } if ((pinfo = Reflector.GetProperty(t, fieldName, true)) != null) { return(new StaticPropertyExpr(source, spanMap, tag, t, fieldName, pinfo)); } if (!isPropName && Reflector.GetArityZeroMethod(t, fieldName, true) != null) { return(new StaticMethodExpr(source, spanMap, tag, t, fieldName, null, new List <HostArg>())); } throw new MissingMemberException(t.Name, fieldName); } else if (instance != null && instance.HasClrType && instance.ClrType != null) { Type instanceType = instance.ClrType; if ((finfo = Reflector.GetField(instanceType, fieldName, false)) != null) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, finfo)); } if ((pinfo = Reflector.GetProperty(instanceType, fieldName, false)) != null) { return(new InstancePropertyExpr(source, spanMap, tag, instance, fieldName, pinfo)); } if (!isPropName && Reflector.GetArityZeroMethod(instanceType, fieldName, false) != null) { return(new InstanceMethodExpr(source, spanMap, tag, instance, fieldName, null, new List <HostArg>())); } if (pcon.IsAssignContext) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null)); // same as InstancePropertyExpr when last arg is null } else { return(new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName)); } } else { // t is null, so we know this is not a static call // If instance is null, we are screwed anyway. // If instance is not null, then we don't have a type. // So we must be in an instance call to a property, field, or 0-arity method. // The code generated by InstanceFieldExpr/InstancePropertyExpr with a null FieldInfo/PropertyInfo // will generate code to do a runtime call to a Reflector method that will check all three. //return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null //return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName); if (pcon.IsAssignContext) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null)); // same as InstancePropertyExpr when last arg is null } else { return(new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName)); } } } //ISeq call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form)); ISeq call; List <Type> typeArgs = null; object fourth = RT.fourth(sform); if (fourth is ISeq && RT.first(fourth) is Symbol && ((Symbol)RT.first(fourth)).Equals(TypeArgsSym)) { // We have a type args supplied for a generic method call // (. thing methodname (type-args type1 ... ) args ...) typeArgs = ParseGenericMethodTypeArgs(RT.next(fourth)); call = RT.listStar(RT.third(sform), RT.next(RT.next(RT.next(RT.next(sform))))); } else { call = RT.third(sform) is ISeq ? (ISeq)RT.third(sform) : RT.next(RT.next(sform)); } if (!(RT.first(call) is Symbol)) { throw new ParseException("Malformed member exception"); } string methodName = Compiler.munge(((Symbol)RT.first(call)).Name); List <HostArg> args = ParseArgs(pcon, RT.next(call)); return(t != null ? (MethodExpr)(new StaticMethodExpr(source, spanMap, tag, t, methodName, typeArgs, args)) : (MethodExpr)(new InstanceMethodExpr(source, spanMap, tag, instance, methodName, typeArgs, args))); }
public Expr Parse(object frm) { ISeq form = (ISeq)frm; // form is one of: // (. x fieldname-sym) // (. x 0-ary-method) // (. x propertyname-sym) // (. x methodname-sym args+) // (. x (methodname-sym args?)) if (RT.Length(form) < 3) { throw new ArgumentException("Malformed member expression, expecting (. target member ... )"); } // determine static or instance // static target must be symbol, either fully.qualified.Typename or Typename that has been imported Type t = Compiler.MaybeType(RT.second(form), false); // at this point, t will be non-null if static Expr instance = null; if (t == null) { instance = Compiler.GenerateAST(RT.second(form)); } bool isFieldOrProperty = false; if (RT.Length(form) == 3 && RT.third(form) is Symbol) { Symbol sym = (Symbol)RT.third(form); if (t != null) { isFieldOrProperty = t.GetField(sym.Name, BindingFlags.Static | BindingFlags.Public) != null || t.GetProperty(sym.Name, BindingFlags.Static | BindingFlags.Public) != null; } else if (instance != null && instance.HasClrType && instance.ClrType != null) { Type instanceType = instance.ClrType; isFieldOrProperty = instanceType.GetField(sym.Name, BindingFlags.Instance | BindingFlags.Public) != null || instanceType.GetProperty(sym.Name, BindingFlags.Instance | BindingFlags.Public) != null; } } if (isFieldOrProperty) { Symbol sym = (Symbol)RT.third(form); if (t != null) { return(new StaticFieldExpr(t, sym.Name)); } else { return(new InstanceFieldExpr(instance, sym.Name)); } } ISeq call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form)); if (!(RT.first(call) is Symbol)) { throw new ArgumentException("Malformed member exception"); } string methodName = ((Symbol)RT.first(call)).Name; IPersistentVector args = PersistentVector.EMPTY; for (ISeq s = RT.next(call); s != null; s = s.next()) { args = args.cons(Compiler.GenerateAST(s.first())); } return(t != null ? (MethodExpr)(new StaticMethodExpr(t, methodName, args)) : (MethodExpr)(new InstanceMethodExpr(instance, methodName, args))); }