annotate MetroWpf/MetroWpf.Framework/Extensions/Dynamic.cs @ 19:09d18d6e5f40

airport work
author stevenh7776 stevenhollidge@hotmail.com
date Thu, 15 Mar 2012 06:59:15 +0000
parents 060f02cd4591
children
rev   line source
15
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1 //Copyright (C) Microsoft Corporation. All rights reserved.
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
3 using System.Collections.Generic;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
4 using System.Linq.Expressions;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
5 using System.Reflection;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
6 using System.Reflection.Emit;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
7 using System.Text;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
8 using System.Threading;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
9
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
10 namespace System.Linq.Dynamic
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
11 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
12 public static class DynamicQueryable
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
13 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
14 public static IQueryable<T> Where<T>(this IQueryable<T> source, string predicate, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
15 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
16 return (IQueryable<T>)Where((IQueryable)source, predicate, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
17 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
18
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
19 public static IQueryable Where(this IQueryable source, string predicate, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
20 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
21 if (source == null) throw new ArgumentNullException("source");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
22 if (predicate == null) throw new ArgumentNullException("predicate");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
23 LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, typeof(bool), predicate, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
24 return source.Provider.CreateQuery(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
25 Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
26 typeof(Queryable), "Where",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
27 new Type[] { source.ElementType },
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
28 source.Expression, Expression.Quote(lambda)));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
29 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
30
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
31 public static IQueryable Select(this IQueryable source, string selector, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
32 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
33 if (source == null) throw new ArgumentNullException("source");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
34 if (selector == null) throw new ArgumentNullException("selector");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
35 LambdaExpression lambda = DynamicExpression.ParseLambda(source.ElementType, null, selector, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
36 return source.Provider.CreateQuery(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
37 Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
38 typeof(Queryable), "Select",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
39 new Type[] { source.ElementType, lambda.Body.Type },
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
40 source.Expression, Expression.Quote(lambda)));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
41 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
42
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
43 public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
44 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
45 return (IQueryable<T>)OrderBy((IQueryable)source, ordering, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
46 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
47
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
48 public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
49 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
50 if (source == null) throw new ArgumentNullException("source");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
51 if (ordering == null) throw new ArgumentNullException("ordering");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
52 ParameterExpression[] parameters = new ParameterExpression[] {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
53 Expression.Parameter(source.ElementType, "") };
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
54 ExpressionParser parser = new ExpressionParser(parameters, ordering, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
55 IEnumerable<DynamicOrdering> orderings = parser.ParseOrdering();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
56 Expression queryExpr = source.Expression;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
57 string methodAsc = "OrderBy";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
58 string methodDesc = "OrderByDescending";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
59 foreach (DynamicOrdering o in orderings)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
60 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
61 queryExpr = Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
62 typeof(Queryable), o.Ascending ? methodAsc : methodDesc,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
63 new Type[] { source.ElementType, o.Selector.Type },
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
64 queryExpr, Expression.Quote(Expression.Lambda(o.Selector, parameters)));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
65 methodAsc = "ThenBy";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
66 methodDesc = "ThenByDescending";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
67 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
68 return source.Provider.CreateQuery(queryExpr);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
69 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
70
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
71 public static IQueryable Take(this IQueryable source, int count)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
72 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
73 if (source == null) throw new ArgumentNullException("source");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
74 return source.Provider.CreateQuery(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
75 Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
76 typeof(Queryable), "Take",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
77 new Type[] { source.ElementType },
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
78 source.Expression, Expression.Constant(count)));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
79 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
80
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
81 public static IQueryable Skip(this IQueryable source, int count)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
82 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
83 if (source == null) throw new ArgumentNullException("source");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
84 return source.Provider.CreateQuery(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
85 Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
86 typeof(Queryable), "Skip",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
87 new Type[] { source.ElementType },
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
88 source.Expression, Expression.Constant(count)));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
89 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
90
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
91 public static IQueryable GroupBy(this IQueryable source, string keySelector, string elementSelector, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
92 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
93 if (source == null) throw new ArgumentNullException("source");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
94 if (keySelector == null) throw new ArgumentNullException("keySelector");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
95 if (elementSelector == null) throw new ArgumentNullException("elementSelector");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
96 LambdaExpression keyLambda = DynamicExpression.ParseLambda(source.ElementType, null, keySelector, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
97 LambdaExpression elementLambda = DynamicExpression.ParseLambda(source.ElementType, null, elementSelector, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
98 return source.Provider.CreateQuery(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
99 Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
100 typeof(Queryable), "GroupBy",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
101 new Type[] { source.ElementType, keyLambda.Body.Type, elementLambda.Body.Type },
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
102 source.Expression, Expression.Quote(keyLambda), Expression.Quote(elementLambda)));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
103 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
104
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
105 public static bool Any(this IQueryable source)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
106 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
107 if (source == null) throw new ArgumentNullException("source");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
108 return (bool)source.Provider.Execute(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
109 Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
110 typeof(Queryable), "Any",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
111 new Type[] { source.ElementType }, source.Expression));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
112 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
113
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
114 public static int Count(this IQueryable source)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
115 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
116 if (source == null) throw new ArgumentNullException("source");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
117 return (int)source.Provider.Execute(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
118 Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
119 typeof(Queryable), "Count",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
120 new Type[] { source.ElementType }, source.Expression));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
121 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
122 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
123
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
124 public abstract class DynamicClass
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
125 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
126 public override string ToString()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
127 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
128 PropertyInfo[] props = this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
129 StringBuilder sb = new StringBuilder();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
130 sb.Append("{");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
131 for (int i = 0; i < props.Length; i++)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
132 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
133 if (i > 0) sb.Append(", ");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
134 sb.Append(props[i].Name);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
135 sb.Append("=");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
136 sb.Append(props[i].GetValue(this, null));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
137 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
138 sb.Append("}");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
139 return sb.ToString();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
140 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
141 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
142
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
143 public class DynamicProperty
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
144 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
145 string name;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
146 Type type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
147
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
148 public DynamicProperty(string name, Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
149 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
150 if (name == null) throw new ArgumentNullException("name");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
151 if (type == null) throw new ArgumentNullException("type");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
152 this.name = name;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
153 this.type = type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
154 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
155
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
156 public string Name
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
157 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
158 get { return name; }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
159 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
160
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
161 public Type Type
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
162 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
163 get { return type; }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
164 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
165 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
166
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
167 public static class DynamicExpression
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
168 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
169 public static Expression Parse(Type resultType, string expression, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
170 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
171 ExpressionParser parser = new ExpressionParser(null, expression, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
172 return parser.Parse(resultType);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
173 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
174
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
175 public static LambdaExpression ParseLambda(Type itType, Type resultType, string expression, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
176 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
177 return ParseLambda(new ParameterExpression[] { Expression.Parameter(itType, "") }, resultType, expression, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
178 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
179
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
180 public static LambdaExpression ParseLambda(ParameterExpression[] parameters, Type resultType, string expression, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
181 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
182 ExpressionParser parser = new ExpressionParser(parameters, expression, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
183 return Expression.Lambda(parser.Parse(resultType), parameters);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
184 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
185
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
186 public static Expression<Func<T, S>> ParseLambda<T, S>(string expression, params object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
187 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
188 return (Expression<Func<T, S>>)ParseLambda(typeof(T), typeof(S), expression, values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
189 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
190
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
191 public static Type CreateClass(params DynamicProperty[] properties)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
192 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
193 return ClassFactory.Instance.GetDynamicClass(properties);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
194 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
195
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
196 public static Type CreateClass(IEnumerable<DynamicProperty> properties)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
197 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
198 return ClassFactory.Instance.GetDynamicClass(properties);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
199 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
200 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
201
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
202 internal class DynamicOrdering
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
203 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
204 public Expression Selector;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
205 public bool Ascending;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
206 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
207
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
208 internal class Signature : IEquatable<Signature>
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
209 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
210 public DynamicProperty[] properties;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
211 public int hashCode;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
212
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
213 public Signature(IEnumerable<DynamicProperty> properties)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
214 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
215 this.properties = properties.ToArray();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
216 hashCode = 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
217 foreach (DynamicProperty p in properties)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
218 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
219 hashCode ^= p.Name.GetHashCode() ^ p.Type.GetHashCode();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
220 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
221 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
222
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
223 public override int GetHashCode()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
224 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
225 return hashCode;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
226 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
227
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
228 public override bool Equals(object obj)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
229 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
230 return obj is Signature ? Equals((Signature)obj) : false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
231 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
232
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
233 public bool Equals(Signature other)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
234 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
235 if (properties.Length != other.properties.Length) return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
236 for (int i = 0; i < properties.Length; i++)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
237 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
238 if (properties[i].Name != other.properties[i].Name ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
239 properties[i].Type != other.properties[i].Type) return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
240 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
241 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
242 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
243 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
244
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
245 internal class ClassFactory
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
246 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
247 public static readonly ClassFactory Instance = new ClassFactory();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
248
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
249 static ClassFactory() { } // Trigger lazy initialization of static fields
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
250
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
251 ModuleBuilder module;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
252 Dictionary<Signature, Type> classes;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
253 int classCount;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
254 ReaderWriterLock rwLock;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
255
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
256 private ClassFactory()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
257 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
258 AssemblyName name = new AssemblyName("DynamicClasses");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
259 AssemblyBuilder assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
260 #if ENABLE_LINQ_PARTIAL_TRUST
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
261 new ReflectionPermission(PermissionState.Unrestricted).Assert();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
262 #endif
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
263 try
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
264 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
265 module = assembly.DefineDynamicModule("Module");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
266 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
267 finally
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
268 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
269 #if ENABLE_LINQ_PARTIAL_TRUST
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
270 PermissionSet.RevertAssert();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
271 #endif
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
272 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
273 classes = new Dictionary<Signature, Type>();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
274 rwLock = new ReaderWriterLock();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
275 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
276
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
277 public Type GetDynamicClass(IEnumerable<DynamicProperty> properties)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
278 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
279 rwLock.AcquireReaderLock(Timeout.Infinite);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
280 try
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
281 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
282 Signature signature = new Signature(properties);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
283 Type type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
284 if (!classes.TryGetValue(signature, out type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
285 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
286 type = CreateDynamicClass(signature.properties);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
287 classes.Add(signature, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
288 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
289 return type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
290 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
291 finally
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
292 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
293 rwLock.ReleaseReaderLock();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
294 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
295 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
296
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
297 Type CreateDynamicClass(DynamicProperty[] properties)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
298 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
299 LockCookie cookie = rwLock.UpgradeToWriterLock(Timeout.Infinite);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
300 try
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
301 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
302 string typeName = "DynamicClass" + (classCount + 1);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
303 #if ENABLE_LINQ_PARTIAL_TRUST
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
304 new ReflectionPermission(PermissionState.Unrestricted).Assert();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
305 #endif
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
306 try
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
307 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
308 TypeBuilder tb = this.module.DefineType(typeName, TypeAttributes.Class |
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
309 TypeAttributes.Public, typeof(DynamicClass));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
310 FieldInfo[] fields = GenerateProperties(tb, properties);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
311 GenerateEquals(tb, fields);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
312 GenerateGetHashCode(tb, fields);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
313 Type result = tb.CreateType();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
314 classCount++;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
315 return result;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
316 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
317 finally
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
318 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
319 #if ENABLE_LINQ_PARTIAL_TRUST
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
320 PermissionSet.RevertAssert();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
321 #endif
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
322 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
323 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
324 finally
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
325 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
326 rwLock.DowngradeFromWriterLock(ref cookie);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
327 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
328 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
329
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
330 FieldInfo[] GenerateProperties(TypeBuilder tb, DynamicProperty[] properties)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
331 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
332 FieldInfo[] fields = new FieldBuilder[properties.Length];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
333 for (int i = 0; i < properties.Length; i++)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
334 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
335 DynamicProperty dp = properties[i];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
336 FieldBuilder fb = tb.DefineField("_" + dp.Name, dp.Type, FieldAttributes.Private);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
337 PropertyBuilder pb = tb.DefineProperty(dp.Name, PropertyAttributes.HasDefault, dp.Type, null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
338 MethodBuilder mbGet = tb.DefineMethod("get_" + dp.Name,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
339 MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
340 dp.Type, Type.EmptyTypes);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
341 ILGenerator genGet = mbGet.GetILGenerator();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
342 genGet.Emit(OpCodes.Ldarg_0);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
343 genGet.Emit(OpCodes.Ldfld, fb);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
344 genGet.Emit(OpCodes.Ret);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
345 MethodBuilder mbSet = tb.DefineMethod("set_" + dp.Name,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
346 MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
347 null, new Type[] { dp.Type });
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
348 ILGenerator genSet = mbSet.GetILGenerator();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
349 genSet.Emit(OpCodes.Ldarg_0);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
350 genSet.Emit(OpCodes.Ldarg_1);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
351 genSet.Emit(OpCodes.Stfld, fb);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
352 genSet.Emit(OpCodes.Ret);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
353 pb.SetGetMethod(mbGet);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
354 pb.SetSetMethod(mbSet);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
355 fields[i] = fb;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
356 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
357 return fields;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
358 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
359
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
360 void GenerateEquals(TypeBuilder tb, FieldInfo[] fields)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
361 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
362 MethodBuilder mb = tb.DefineMethod("Equals",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
363 MethodAttributes.Public | MethodAttributes.ReuseSlot |
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
364 MethodAttributes.Virtual | MethodAttributes.HideBySig,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
365 typeof(bool), new Type[] { typeof(object) });
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
366 ILGenerator gen = mb.GetILGenerator();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
367 LocalBuilder other = gen.DeclareLocal(tb);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
368 Label next = gen.DefineLabel();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
369 gen.Emit(OpCodes.Ldarg_1);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
370 gen.Emit(OpCodes.Isinst, tb);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
371 gen.Emit(OpCodes.Stloc, other);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
372 gen.Emit(OpCodes.Ldloc, other);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
373 gen.Emit(OpCodes.Brtrue_S, next);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
374 gen.Emit(OpCodes.Ldc_I4_0);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
375 gen.Emit(OpCodes.Ret);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
376 gen.MarkLabel(next);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
377 foreach (FieldInfo field in fields)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
378 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
379 Type ft = field.FieldType;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
380 Type ct = typeof(EqualityComparer<>).MakeGenericType(ft);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
381 next = gen.DefineLabel();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
382 gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
383 gen.Emit(OpCodes.Ldarg_0);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
384 gen.Emit(OpCodes.Ldfld, field);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
385 gen.Emit(OpCodes.Ldloc, other);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
386 gen.Emit(OpCodes.Ldfld, field);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
387 gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("Equals", new Type[] { ft, ft }), null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
388 gen.Emit(OpCodes.Brtrue_S, next);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
389 gen.Emit(OpCodes.Ldc_I4_0);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
390 gen.Emit(OpCodes.Ret);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
391 gen.MarkLabel(next);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
392 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
393 gen.Emit(OpCodes.Ldc_I4_1);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
394 gen.Emit(OpCodes.Ret);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
395 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
396
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
397 void GenerateGetHashCode(TypeBuilder tb, FieldInfo[] fields)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
398 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
399 MethodBuilder mb = tb.DefineMethod("GetHashCode",
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
400 MethodAttributes.Public | MethodAttributes.ReuseSlot |
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
401 MethodAttributes.Virtual | MethodAttributes.HideBySig,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
402 typeof(int), Type.EmptyTypes);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
403 ILGenerator gen = mb.GetILGenerator();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
404 gen.Emit(OpCodes.Ldc_I4_0);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
405 foreach (FieldInfo field in fields)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
406 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
407 Type ft = field.FieldType;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
408 Type ct = typeof(EqualityComparer<>).MakeGenericType(ft);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
409 gen.EmitCall(OpCodes.Call, ct.GetMethod("get_Default"), null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
410 gen.Emit(OpCodes.Ldarg_0);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
411 gen.Emit(OpCodes.Ldfld, field);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
412 gen.EmitCall(OpCodes.Callvirt, ct.GetMethod("GetHashCode", new Type[] { ft }), null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
413 gen.Emit(OpCodes.Xor);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
414 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
415 gen.Emit(OpCodes.Ret);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
416 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
417 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
418
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
419 public sealed class ParseException : Exception
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
420 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
421 int position;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
422
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
423 public ParseException(string message, int position)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
424 : base(message)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
425 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
426 this.position = position;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
427 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
428
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
429 public int Position
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
430 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
431 get { return position; }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
432 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
433
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
434 public override string ToString()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
435 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
436 return string.Format(Res.ParseExceptionFormat, Message, position);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
437 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
438 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
439
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
440 internal class ExpressionParser
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
441 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
442 struct Token
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
443 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
444 public TokenId id;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
445 public string text;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
446 public int pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
447 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
448
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
449 enum TokenId
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
450 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
451 Unknown,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
452 End,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
453 Identifier,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
454 StringLiteral,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
455 IntegerLiteral,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
456 RealLiteral,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
457 Exclamation,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
458 Percent,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
459 Amphersand,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
460 OpenParen,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
461 CloseParen,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
462 Asterisk,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
463 Plus,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
464 Comma,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
465 Minus,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
466 Dot,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
467 Slash,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
468 Colon,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
469 LessThan,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
470 Equal,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
471 GreaterThan,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
472 Question,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
473 OpenBracket,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
474 CloseBracket,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
475 Bar,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
476 ExclamationEqual,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
477 DoubleAmphersand,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
478 LessThanEqual,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
479 LessGreater,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
480 DoubleEqual,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
481 GreaterThanEqual,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
482 DoubleBar
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
483 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
484
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
485 interface ILogicalSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
486 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
487 void F(bool x, bool y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
488 void F(bool? x, bool? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
489 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
490
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
491 interface IArithmeticSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
492 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
493 void F(int x, int y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
494 void F(uint x, uint y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
495 void F(long x, long y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
496 void F(ulong x, ulong y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
497 void F(float x, float y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
498 void F(double x, double y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
499 void F(decimal x, decimal y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
500 void F(int? x, int? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
501 void F(uint? x, uint? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
502 void F(long? x, long? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
503 void F(ulong? x, ulong? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
504 void F(float? x, float? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
505 void F(double? x, double? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
506 void F(decimal? x, decimal? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
507 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
508
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
509 interface IRelationalSignatures : IArithmeticSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
510 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
511 void F(string x, string y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
512 void F(char x, char y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
513 void F(DateTime x, DateTime y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
514 void F(TimeSpan x, TimeSpan y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
515 void F(char? x, char? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
516 void F(DateTime? x, DateTime? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
517 void F(TimeSpan? x, TimeSpan? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
518 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
519
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
520 interface IEqualitySignatures : IRelationalSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
521 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
522 void F(bool x, bool y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
523 void F(bool? x, bool? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
524 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
525
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
526 interface IAddSignatures : IArithmeticSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
527 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
528 void F(DateTime x, TimeSpan y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
529 void F(TimeSpan x, TimeSpan y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
530 void F(DateTime? x, TimeSpan? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
531 void F(TimeSpan? x, TimeSpan? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
532 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
533
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
534 interface ISubtractSignatures : IAddSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
535 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
536 void F(DateTime x, DateTime y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
537 void F(DateTime? x, DateTime? y);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
538 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
539
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
540 interface INegationSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
541 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
542 void F(int x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
543 void F(long x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
544 void F(float x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
545 void F(double x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
546 void F(decimal x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
547 void F(int? x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
548 void F(long? x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
549 void F(float? x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
550 void F(double? x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
551 void F(decimal? x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
552 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
553
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
554 interface INotSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
555 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
556 void F(bool x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
557 void F(bool? x);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
558 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
559
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
560 interface IEnumerableSignatures
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
561 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
562 void Where(bool predicate);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
563 void Any();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
564 void Any(bool predicate);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
565 void All(bool predicate);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
566 void Count();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
567 void Count(bool predicate);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
568 void Min(object selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
569 void Max(object selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
570 void Sum(int selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
571 void Sum(int? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
572 void Sum(long selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
573 void Sum(long? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
574 void Sum(float selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
575 void Sum(float? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
576 void Sum(double selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
577 void Sum(double? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
578 void Sum(decimal selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
579 void Sum(decimal? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
580 void Average(int selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
581 void Average(int? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
582 void Average(long selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
583 void Average(long? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
584 void Average(float selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
585 void Average(float? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
586 void Average(double selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
587 void Average(double? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
588 void Average(decimal selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
589 void Average(decimal? selector);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
590 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
591
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
592 static readonly Type[] predefinedTypes = {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
593 typeof(Object),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
594 typeof(Boolean),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
595 typeof(Char),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
596 typeof(String),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
597 typeof(SByte),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
598 typeof(Byte),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
599 typeof(Int16),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
600 typeof(UInt16),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
601 typeof(Int32),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
602 typeof(UInt32),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
603 typeof(Int64),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
604 typeof(UInt64),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
605 typeof(Single),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
606 typeof(Double),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
607 typeof(Decimal),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
608 typeof(DateTime),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
609 typeof(TimeSpan),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
610 typeof(Guid),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
611 typeof(Math),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
612 typeof(Convert)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
613 };
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
614
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
615 static readonly Expression trueLiteral = Expression.Constant(true);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
616 static readonly Expression falseLiteral = Expression.Constant(false);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
617 static readonly Expression nullLiteral = Expression.Constant(null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
618
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
619 static readonly string keywordIt = "it";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
620 static readonly string keywordIif = "iif";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
621 static readonly string keywordNew = "new";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
622
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
623 static Dictionary<string, object> keywords;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
624
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
625 Dictionary<string, object> symbols;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
626 IDictionary<string, object> externals;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
627 Dictionary<Expression, string> literals;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
628 ParameterExpression it;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
629 string text;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
630 int textPos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
631 int textLen;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
632 char ch;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
633 Token token;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
634
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
635 public ExpressionParser(ParameterExpression[] parameters, string expression, object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
636 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
637 if (expression == null) throw new ArgumentNullException("expression");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
638 if (keywords == null) keywords = CreateKeywords();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
639 symbols = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
640 literals = new Dictionary<Expression, string>();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
641 if (parameters != null) ProcessParameters(parameters);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
642 if (values != null) ProcessValues(values);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
643 text = expression;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
644 textLen = text.Length;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
645 SetTextPos(0);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
646 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
647 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
648
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
649 void ProcessParameters(ParameterExpression[] parameters)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
650 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
651 foreach (ParameterExpression pe in parameters)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
652 if (!String.IsNullOrEmpty(pe.Name))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
653 AddSymbol(pe.Name, pe);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
654 if (parameters.Length == 1 && String.IsNullOrEmpty(parameters[0].Name))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
655 it = parameters[0];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
656 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
657
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
658 void ProcessValues(object[] values)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
659 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
660 for (int i = 0; i < values.Length; i++)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
661 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
662 object value = values[i];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
663 if (i == values.Length - 1 && value is IDictionary<string, object>)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
664 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
665 externals = (IDictionary<string, object>)value;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
666 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
667 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
668 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
669 AddSymbol("@" + i.ToString(System.Globalization.CultureInfo.InvariantCulture), value);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
670 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
671 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
672 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
673
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
674 void AddSymbol(string name, object value)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
675 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
676 if (symbols.ContainsKey(name))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
677 throw ParseError(Res.DuplicateIdentifier, name);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
678 symbols.Add(name, value);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
679 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
680
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
681 public Expression Parse(Type resultType)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
682 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
683 int exprPos = token.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
684 Expression expr = ParseExpression();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
685 if (resultType != null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
686 if ((expr = PromoteExpression(expr, resultType, true)) == null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
687 throw ParseError(exprPos, Res.ExpressionTypeMismatch, GetTypeName(resultType));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
688 ValidateToken(TokenId.End, Res.SyntaxError);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
689 return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
690 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
691
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
692 #pragma warning disable 0219
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
693 public IEnumerable<DynamicOrdering> ParseOrdering()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
694 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
695 List<DynamicOrdering> orderings = new List<DynamicOrdering>();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
696 while (true)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
697 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
698 Expression expr = ParseExpression();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
699 bool ascending = true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
700 if (TokenIdentifierIs("asc") || TokenIdentifierIs("ascending"))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
701 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
702 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
703 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
704 else if (TokenIdentifierIs("desc") || TokenIdentifierIs("descending"))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
705 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
706 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
707 ascending = false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
708 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
709 orderings.Add(new DynamicOrdering { Selector = expr, Ascending = ascending });
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
710 if (token.id != TokenId.Comma) break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
711 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
712 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
713 ValidateToken(TokenId.End, Res.SyntaxError);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
714 return orderings;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
715 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
716 #pragma warning restore 0219
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
717
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
718 // ?: operator
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
719 Expression ParseExpression()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
720 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
721 int errorPos = token.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
722 Expression expr = ParseLogicalOr();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
723 if (token.id == TokenId.Question)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
724 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
725 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
726 Expression expr1 = ParseExpression();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
727 ValidateToken(TokenId.Colon, Res.ColonExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
728 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
729 Expression expr2 = ParseExpression();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
730 expr = GenerateConditional(expr, expr1, expr2, errorPos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
731 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
732 return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
733 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
734
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
735 // ||, or operator
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
736 Expression ParseLogicalOr()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
737 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
738 Expression left = ParseLogicalAnd();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
739 while (token.id == TokenId.DoubleBar || TokenIdentifierIs("or"))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
740 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
741 Token op = token;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
742 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
743 Expression right = ParseLogicalAnd();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
744 CheckAndPromoteOperands(typeof(ILogicalSignatures), op.text, ref left, ref right, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
745 left = Expression.OrElse(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
746 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
747 return left;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
748 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
749
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
750 // &&, and operator
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
751 Expression ParseLogicalAnd()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
752 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
753 Expression left = ParseComparison();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
754 while (token.id == TokenId.DoubleAmphersand || TokenIdentifierIs("and"))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
755 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
756 Token op = token;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
757 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
758 Expression right = ParseComparison();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
759 CheckAndPromoteOperands(typeof(ILogicalSignatures), op.text, ref left, ref right, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
760 left = Expression.AndAlso(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
761 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
762 return left;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
763 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
764
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
765 // =, ==, !=, <>, >, >=, <, <= operators
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
766 Expression ParseComparison()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
767 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
768 Expression left = ParseAdditive();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
769 while (token.id == TokenId.Equal || token.id == TokenId.DoubleEqual ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
770 token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
771 token.id == TokenId.GreaterThan || token.id == TokenId.GreaterThanEqual ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
772 token.id == TokenId.LessThan || token.id == TokenId.LessThanEqual)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
773 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
774 Token op = token;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
775 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
776 Expression right = ParseAdditive();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
777 bool isEquality = op.id == TokenId.Equal || op.id == TokenId.DoubleEqual ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
778 op.id == TokenId.ExclamationEqual || op.id == TokenId.LessGreater;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
779 if (isEquality && !left.Type.IsValueType && !right.Type.IsValueType)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
780 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
781 if (left.Type != right.Type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
782 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
783 if (left.Type.IsAssignableFrom(right.Type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
784 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
785 right = Expression.Convert(right, left.Type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
786 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
787 else if (right.Type.IsAssignableFrom(left.Type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
788 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
789 left = Expression.Convert(left, right.Type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
790 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
791 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
792 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
793 throw IncompatibleOperandsError(op.text, left, right, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
794 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
795 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
796 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
797 else if (IsEnumType(left.Type) || IsEnumType(right.Type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
798 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
799 if (left.Type != right.Type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
800 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
801 Expression e;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
802 if ((e = PromoteExpression(right, left.Type, true)) != null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
803 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
804 right = e;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
805 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
806 else if ((e = PromoteExpression(left, right.Type, true)) != null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
807 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
808 left = e;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
809 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
810 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
811 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
812 throw IncompatibleOperandsError(op.text, left, right, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
813 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
814 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
815 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
816 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
817 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
818 CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
819 op.text, ref left, ref right, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
820 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
821 switch (op.id)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
822 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
823 case TokenId.Equal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
824 case TokenId.DoubleEqual:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
825 left = GenerateEqual(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
826 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
827 case TokenId.ExclamationEqual:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
828 case TokenId.LessGreater:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
829 left = GenerateNotEqual(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
830 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
831 case TokenId.GreaterThan:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
832 left = GenerateGreaterThan(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
833 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
834 case TokenId.GreaterThanEqual:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
835 left = GenerateGreaterThanEqual(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
836 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
837 case TokenId.LessThan:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
838 left = GenerateLessThan(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
839 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
840 case TokenId.LessThanEqual:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
841 left = GenerateLessThanEqual(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
842 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
843 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
844 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
845 return left;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
846 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
847
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
848 // +, -, & operators
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
849 Expression ParseAdditive()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
850 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
851 Expression left = ParseMultiplicative();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
852 while (token.id == TokenId.Plus || token.id == TokenId.Minus ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
853 token.id == TokenId.Amphersand)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
854 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
855 Token op = token;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
856 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
857 Expression right = ParseMultiplicative();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
858 switch (op.id)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
859 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
860 case TokenId.Plus:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
861 if (left.Type == typeof(string) || right.Type == typeof(string))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
862 goto case TokenId.Amphersand;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
863 CheckAndPromoteOperands(typeof(IAddSignatures), op.text, ref left, ref right, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
864 left = GenerateAdd(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
865 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
866 case TokenId.Minus:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
867 CheckAndPromoteOperands(typeof(ISubtractSignatures), op.text, ref left, ref right, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
868 left = GenerateSubtract(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
869 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
870 case TokenId.Amphersand:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
871 left = GenerateStringConcat(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
872 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
873 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
874 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
875 return left;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
876 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
877
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
878 // *, /, %, mod operators
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
879 Expression ParseMultiplicative()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
880 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
881 Expression left = ParseUnary();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
882 while (token.id == TokenId.Asterisk || token.id == TokenId.Slash ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
883 token.id == TokenId.Percent || TokenIdentifierIs("mod"))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
884 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
885 Token op = token;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
886 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
887 Expression right = ParseUnary();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
888 CheckAndPromoteOperands(typeof(IArithmeticSignatures), op.text, ref left, ref right, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
889 switch (op.id)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
890 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
891 case TokenId.Asterisk:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
892 left = Expression.Multiply(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
893 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
894 case TokenId.Slash:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
895 left = Expression.Divide(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
896 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
897 case TokenId.Percent:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
898 case TokenId.Identifier:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
899 left = Expression.Modulo(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
900 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
901 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
902 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
903 return left;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
904 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
905
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
906 // -, !, not unary operators
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
907 Expression ParseUnary()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
908 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
909 if (token.id == TokenId.Minus || token.id == TokenId.Exclamation ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
910 TokenIdentifierIs("not"))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
911 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
912 Token op = token;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
913 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
914 if (op.id == TokenId.Minus && (token.id == TokenId.IntegerLiteral ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
915 token.id == TokenId.RealLiteral))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
916 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
917 token.text = "-" + token.text;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
918 token.pos = op.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
919 return ParsePrimary();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
920 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
921 Expression expr = ParseUnary();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
922 if (op.id == TokenId.Minus)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
923 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
924 CheckAndPromoteOperand(typeof(INegationSignatures), op.text, ref expr, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
925 expr = Expression.Negate(expr);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
926 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
927 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
928 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
929 CheckAndPromoteOperand(typeof(INotSignatures), op.text, ref expr, op.pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
930 expr = Expression.Not(expr);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
931 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
932 return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
933 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
934 return ParsePrimary();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
935 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
936
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
937 Expression ParsePrimary()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
938 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
939 Expression expr = ParsePrimaryStart();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
940 while (true)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
941 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
942 if (token.id == TokenId.Dot)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
943 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
944 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
945 expr = ParseMemberAccess(null, expr);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
946 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
947 else if (token.id == TokenId.OpenBracket)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
948 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
949 expr = ParseElementAccess(expr);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
950 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
951 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
952 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
953 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
954 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
955 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
956 return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
957 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
958
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
959 Expression ParsePrimaryStart()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
960 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
961 switch (token.id)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
962 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
963 case TokenId.Identifier:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
964 return ParseIdentifier();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
965 case TokenId.StringLiteral:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
966 return ParseStringLiteral();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
967 case TokenId.IntegerLiteral:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
968 return ParseIntegerLiteral();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
969 case TokenId.RealLiteral:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
970 return ParseRealLiteral();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
971 case TokenId.OpenParen:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
972 return ParseParenExpression();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
973 default:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
974 throw ParseError(Res.ExpressionExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
975 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
976 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
977
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
978 Expression ParseStringLiteral()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
979 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
980 ValidateToken(TokenId.StringLiteral);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
981 char quote = token.text[0];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
982 string s = token.text.Substring(1, token.text.Length - 2);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
983 int start = 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
984 while (true)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
985 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
986 int i = s.IndexOf(quote, start);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
987 if (i < 0) break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
988 s = s.Remove(i, 1);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
989 start = i + 1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
990 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
991 if (quote == '\'')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
992 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
993 if (s.Length != 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
994 throw ParseError(Res.InvalidCharacterLiteral);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
995 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
996 return CreateLiteral(s[0], s);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
997 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
998 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
999 return CreateLiteral(s, s);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1000 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1001
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1002 Expression ParseIntegerLiteral()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1003 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1004 ValidateToken(TokenId.IntegerLiteral);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1005 string text = token.text;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1006 if (text[0] != '-')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1007 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1008 ulong value;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1009 if (!UInt64.TryParse(text, out value))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1010 throw ParseError(Res.InvalidIntegerLiteral, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1011 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1012 if (value <= (ulong)Int32.MaxValue) return CreateLiteral((int)value, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1013 if (value <= (ulong)UInt32.MaxValue) return CreateLiteral((uint)value, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1014 if (value <= (ulong)Int64.MaxValue) return CreateLiteral((long)value, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1015 return CreateLiteral(value, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1016 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1017 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1018 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1019 long value;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1020 if (!Int64.TryParse(text, out value))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1021 throw ParseError(Res.InvalidIntegerLiteral, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1022 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1023 if (value >= Int32.MinValue && value <= Int32.MaxValue)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1024 return CreateLiteral((int)value, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1025 return CreateLiteral(value, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1026 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1027 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1028
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1029 Expression ParseRealLiteral()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1030 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1031 ValidateToken(TokenId.RealLiteral);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1032 string text = token.text;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1033 object value = null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1034 char last = text[text.Length - 1];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1035 if (last == 'F' || last == 'f')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1036 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1037 float f;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1038 if (Single.TryParse(text.Substring(0, text.Length - 1), out f)) value = f;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1039 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1040 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1041 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1042 double d;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1043 if (Double.TryParse(text, out d)) value = d;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1044 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1045 if (value == null) throw ParseError(Res.InvalidRealLiteral, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1046 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1047 return CreateLiteral(value, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1048 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1049
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1050 Expression CreateLiteral(object value, string text)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1051 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1052 ConstantExpression expr = Expression.Constant(value);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1053 literals.Add(expr, text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1054 return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1055 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1056
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1057 Expression ParseParenExpression()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1058 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1059 ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1060 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1061 Expression e = ParseExpression();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1062 ValidateToken(TokenId.CloseParen, Res.CloseParenOrOperatorExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1063 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1064 return e;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1065 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1066
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1067 Expression ParseIdentifier()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1068 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1069 ValidateToken(TokenId.Identifier);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1070 object value;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1071 if (keywords.TryGetValue(token.text, out value))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1072 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1073 if (value is Type) return ParseTypeAccess((Type)value);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1074 if (value == (object)keywordIt) return ParseIt();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1075 if (value == (object)keywordIif) return ParseIif();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1076 if (value == (object)keywordNew) return ParseNew();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1077 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1078 return (Expression)value;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1079 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1080 if (symbols.TryGetValue(token.text, out value) ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1081 externals != null && externals.TryGetValue(token.text, out value))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1082 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1083 Expression expr = value as Expression;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1084 if (expr == null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1085 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1086 expr = Expression.Constant(value);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1087 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1088 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1089 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1090 LambdaExpression lambda = expr as LambdaExpression;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1091 if (lambda != null) return ParseLambdaInvocation(lambda);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1092 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1093 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1094 return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1095 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1096 if (it != null) return ParseMemberAccess(null, it);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1097 throw ParseError(Res.UnknownIdentifier, token.text);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1098 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1099
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1100 Expression ParseIt()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1101 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1102 if (it == null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1103 throw ParseError(Res.NoItInScope);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1104 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1105 return it;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1106 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1107
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1108 Expression ParseIif()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1109 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1110 int errorPos = token.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1111 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1112 Expression[] args = ParseArgumentList();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1113 if (args.Length != 3)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1114 throw ParseError(errorPos, Res.IifRequiresThreeArgs);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1115 return GenerateConditional(args[0], args[1], args[2], errorPos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1116 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1117
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1118 Expression GenerateConditional(Expression test, Expression expr1, Expression expr2, int errorPos)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1119 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1120 if (test.Type != typeof(bool))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1121 throw ParseError(errorPos, Res.FirstExprMustBeBool);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1122 if (expr1.Type != expr2.Type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1123 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1124 Expression expr1as2 = expr2 != nullLiteral ? PromoteExpression(expr1, expr2.Type, true) : null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1125 Expression expr2as1 = expr1 != nullLiteral ? PromoteExpression(expr2, expr1.Type, true) : null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1126 if (expr1as2 != null && expr2as1 == null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1127 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1128 expr1 = expr1as2;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1129 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1130 else if (expr2as1 != null && expr1as2 == null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1131 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1132 expr2 = expr2as1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1133 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1134 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1135 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1136 string type1 = expr1 != nullLiteral ? expr1.Type.Name : "null";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1137 string type2 = expr2 != nullLiteral ? expr2.Type.Name : "null";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1138 if (expr1as2 != null && expr2as1 != null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1139 throw ParseError(errorPos, Res.BothTypesConvertToOther, type1, type2);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1140 throw ParseError(errorPos, Res.NeitherTypeConvertsToOther, type1, type2);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1141 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1142 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1143 return Expression.Condition(test, expr1, expr2);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1144 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1145
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1146 Expression ParseNew()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1147 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1148 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1149 ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1150 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1151 List<DynamicProperty> properties = new List<DynamicProperty>();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1152 List<Expression> expressions = new List<Expression>();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1153 while (true)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1154 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1155 int exprPos = token.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1156 Expression expr = ParseExpression();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1157 string propName;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1158 if (TokenIdentifierIs("as"))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1159 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1160 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1161 propName = GetIdentifier();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1162 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1163 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1164 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1165 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1166 MemberExpression me = expr as MemberExpression;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1167 if (me == null) throw ParseError(exprPos, Res.MissingAsClause);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1168 propName = me.Member.Name;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1169 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1170 expressions.Add(expr);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1171 properties.Add(new DynamicProperty(propName, expr.Type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1172 if (token.id != TokenId.Comma) break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1173 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1174 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1175 ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1176 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1177 Type type = DynamicExpression.CreateClass(properties);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1178 MemberBinding[] bindings = new MemberBinding[properties.Count];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1179 for (int i = 0; i < bindings.Length; i++)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1180 bindings[i] = Expression.Bind(type.GetProperty(properties[i].Name), expressions[i]);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1181 return Expression.MemberInit(Expression.New(type), bindings);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1182 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1183
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1184 Expression ParseLambdaInvocation(LambdaExpression lambda)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1185 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1186 int errorPos = token.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1187 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1188 Expression[] args = ParseArgumentList();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1189 MethodBase method;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1190 if (FindMethod(lambda.Type, "Invoke", false, args, out method) != 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1191 throw ParseError(errorPos, Res.ArgsIncompatibleWithLambda);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1192 return Expression.Invoke(lambda, args);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1193 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1194
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1195 Expression ParseTypeAccess(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1196 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1197 int errorPos = token.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1198 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1199 if (token.id == TokenId.Question)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1200 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1201 if (!type.IsValueType || IsNullableType(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1202 throw ParseError(errorPos, Res.TypeHasNoNullableForm, GetTypeName(type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1203 type = typeof(Nullable<>).MakeGenericType(type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1204 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1205 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1206 if (token.id == TokenId.OpenParen)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1207 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1208 Expression[] args = ParseArgumentList();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1209 MethodBase method;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1210 switch (FindBestMethod(type.GetConstructors(), args, out method))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1211 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1212 case 0:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1213 if (args.Length == 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1214 return GenerateConversion(args[0], type, errorPos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1215 throw ParseError(errorPos, Res.NoMatchingConstructor, GetTypeName(type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1216 case 1:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1217 return Expression.New((ConstructorInfo)method, args);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1218 default:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1219 throw ParseError(errorPos, Res.AmbiguousConstructorInvocation, GetTypeName(type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1220 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1221 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1222 ValidateToken(TokenId.Dot, Res.DotOrOpenParenExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1223 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1224 return ParseMemberAccess(type, null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1225 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1226
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1227 Expression GenerateConversion(Expression expr, Type type, int errorPos)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1228 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1229 Type exprType = expr.Type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1230 if (exprType == type) return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1231 if (exprType.IsValueType && type.IsValueType)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1232 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1233 if ((IsNullableType(exprType) || IsNullableType(type)) &&
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1234 GetNonNullableType(exprType) == GetNonNullableType(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1235 return Expression.Convert(expr, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1236 if ((IsNumericType(exprType) || IsEnumType(exprType)) &&
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1237 (IsNumericType(type)) || IsEnumType(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1238 return Expression.ConvertChecked(expr, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1239 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1240 if (exprType.IsAssignableFrom(type) || type.IsAssignableFrom(exprType) ||
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1241 exprType.IsInterface || type.IsInterface)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1242 return Expression.Convert(expr, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1243 throw ParseError(errorPos, Res.CannotConvertValue,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1244 GetTypeName(exprType), GetTypeName(type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1245 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1246
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1247 Expression ParseMemberAccess(Type type, Expression instance)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1248 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1249 if (instance != null) type = instance.Type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1250 int errorPos = token.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1251 string id = GetIdentifier();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1252 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1253 if (token.id == TokenId.OpenParen)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1254 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1255 if (instance != null && type != typeof(string))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1256 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1257 Type enumerableType = FindGenericType(typeof(IEnumerable<>), type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1258 if (enumerableType != null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1259 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1260 Type elementType = enumerableType.GetGenericArguments()[0];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1261 return ParseAggregate(instance, elementType, id, errorPos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1262 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1263 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1264 Expression[] args = ParseArgumentList();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1265 MethodBase mb;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1266 switch (FindMethod(type, id, instance == null, args, out mb))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1267 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1268 case 0:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1269 throw ParseError(errorPos, Res.NoApplicableMethod,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1270 id, GetTypeName(type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1271 case 1:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1272 MethodInfo method = (MethodInfo)mb;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1273 if (!IsPredefinedType(method.DeclaringType))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1274 throw ParseError(errorPos, Res.MethodsAreInaccessible, GetTypeName(method.DeclaringType));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1275 if (method.ReturnType == typeof(void))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1276 throw ParseError(errorPos, Res.MethodIsVoid,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1277 id, GetTypeName(method.DeclaringType));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1278 return Expression.Call(instance, (MethodInfo)method, args);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1279 default:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1280 throw ParseError(errorPos, Res.AmbiguousMethodInvocation,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1281 id, GetTypeName(type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1282 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1283 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1284 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1285 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1286 MemberInfo member = FindPropertyOrField(type, id, instance == null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1287 if (member == null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1288 throw ParseError(errorPos, Res.UnknownPropertyOrField,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1289 id, GetTypeName(type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1290 return member is PropertyInfo ?
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1291 Expression.Property(instance, (PropertyInfo)member) :
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1292 Expression.Field(instance, (FieldInfo)member);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1293 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1294 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1295
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1296 static Type FindGenericType(Type generic, Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1297 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1298 while (type != null && type != typeof(object))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1299 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1300 if (type.IsGenericType && type.GetGenericTypeDefinition() == generic) return type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1301 if (generic.IsInterface)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1302 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1303 foreach (Type intfType in type.GetInterfaces())
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1304 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1305 Type found = FindGenericType(generic, intfType);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1306 if (found != null) return found;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1307 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1308 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1309 type = type.BaseType;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1310 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1311 return null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1312 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1313
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1314 Expression ParseAggregate(Expression instance, Type elementType, string methodName, int errorPos)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1315 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1316 ParameterExpression outerIt = it;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1317 ParameterExpression innerIt = Expression.Parameter(elementType, "");
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1318 it = innerIt;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1319 Expression[] args = ParseArgumentList();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1320 it = outerIt;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1321 MethodBase signature;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1322 if (FindMethod(typeof(IEnumerableSignatures), methodName, false, args, out signature) != 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1323 throw ParseError(errorPos, Res.NoApplicableAggregate, methodName);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1324 Type[] typeArgs;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1325 if (signature.Name == "Min" || signature.Name == "Max")
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1326 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1327 typeArgs = new Type[] { elementType, args[0].Type };
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1328 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1329 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1330 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1331 typeArgs = new Type[] { elementType };
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1332 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1333 if (args.Length == 0)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1334 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1335 args = new Expression[] { instance };
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1336 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1337 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1338 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1339 args = new Expression[] { instance, Expression.Lambda(args[0], innerIt) };
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1340 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1341 return Expression.Call(typeof(Enumerable), signature.Name, typeArgs, args);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1342 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1343
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1344 Expression[] ParseArgumentList()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1345 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1346 ValidateToken(TokenId.OpenParen, Res.OpenParenExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1347 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1348 Expression[] args = token.id != TokenId.CloseParen ? ParseArguments() : new Expression[0];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1349 ValidateToken(TokenId.CloseParen, Res.CloseParenOrCommaExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1350 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1351 return args;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1352 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1353
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1354 Expression[] ParseArguments()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1355 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1356 List<Expression> argList = new List<Expression>();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1357 while (true)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1358 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1359 argList.Add(ParseExpression());
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1360 if (token.id != TokenId.Comma) break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1361 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1362 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1363 return argList.ToArray();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1364 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1365
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1366 Expression ParseElementAccess(Expression expr)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1367 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1368 int errorPos = token.pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1369 ValidateToken(TokenId.OpenBracket, Res.OpenParenExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1370 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1371 Expression[] args = ParseArguments();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1372 ValidateToken(TokenId.CloseBracket, Res.CloseBracketOrCommaExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1373 NextToken();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1374 if (expr.Type.IsArray)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1375 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1376 if (expr.Type.GetArrayRank() != 1 || args.Length != 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1377 throw ParseError(errorPos, Res.CannotIndexMultiDimArray);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1378 Expression index = PromoteExpression(args[0], typeof(int), true);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1379 if (index == null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1380 throw ParseError(errorPos, Res.InvalidIndex);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1381 return Expression.ArrayIndex(expr, index);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1382 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1383 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1384 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1385 MethodBase mb;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1386 switch (FindIndexer(expr.Type, args, out mb))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1387 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1388 case 0:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1389 throw ParseError(errorPos, Res.NoApplicableIndexer,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1390 GetTypeName(expr.Type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1391 case 1:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1392 return Expression.Call(expr, (MethodInfo)mb, args);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1393 default:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1394 throw ParseError(errorPos, Res.AmbiguousIndexerInvocation,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1395 GetTypeName(expr.Type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1396 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1397 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1398 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1399
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1400 static bool IsPredefinedType(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1401 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1402 foreach (Type t in predefinedTypes) if (t == type) return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1403 return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1404 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1405
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1406 static bool IsNullableType(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1407 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1408 return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1409 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1410
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1411 static Type GetNonNullableType(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1412 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1413 return IsNullableType(type) ? type.GetGenericArguments()[0] : type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1414 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1415
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1416 static string GetTypeName(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1417 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1418 Type baseType = GetNonNullableType(type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1419 string s = baseType.Name;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1420 if (type != baseType) s += '?';
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1421 return s;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1422 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1423
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1424 static bool IsNumericType(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1425 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1426 return GetNumericTypeKind(type) != 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1427 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1428
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1429 static bool IsSignedIntegralType(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1430 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1431 return GetNumericTypeKind(type) == 2;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1432 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1433
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1434 static bool IsUnsignedIntegralType(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1435 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1436 return GetNumericTypeKind(type) == 3;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1437 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1438
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1439 static int GetNumericTypeKind(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1440 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1441 type = GetNonNullableType(type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1442 if (type.IsEnum) return 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1443 switch (Type.GetTypeCode(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1444 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1445 case TypeCode.Char:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1446 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1447 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1448 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1449 return 1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1450 case TypeCode.SByte:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1451 case TypeCode.Int16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1452 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1453 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1454 return 2;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1455 case TypeCode.Byte:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1456 case TypeCode.UInt16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1457 case TypeCode.UInt32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1458 case TypeCode.UInt64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1459 return 3;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1460 default:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1461 return 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1462 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1463 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1464
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1465 static bool IsEnumType(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1466 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1467 return GetNonNullableType(type).IsEnum;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1468 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1469
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1470 void CheckAndPromoteOperand(Type signatures, string opName, ref Expression expr, int errorPos)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1471 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1472 Expression[] args = new Expression[] { expr };
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1473 MethodBase method;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1474 if (FindMethod(signatures, "F", false, args, out method) != 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1475 throw ParseError(errorPos, Res.IncompatibleOperand,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1476 opName, GetTypeName(args[0].Type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1477 expr = args[0];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1478 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1479
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1480 void CheckAndPromoteOperands(Type signatures, string opName, ref Expression left, ref Expression right, int errorPos)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1481 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1482 Expression[] args = new Expression[] { left, right };
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1483 MethodBase method;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1484 if (FindMethod(signatures, "F", false, args, out method) != 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1485 throw IncompatibleOperandsError(opName, left, right, errorPos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1486 left = args[0];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1487 right = args[1];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1488 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1489
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1490 Exception IncompatibleOperandsError(string opName, Expression left, Expression right, int pos)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1491 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1492 return ParseError(pos, Res.IncompatibleOperands,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1493 opName, GetTypeName(left.Type), GetTypeName(right.Type));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1494 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1495
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1496 MemberInfo FindPropertyOrField(Type type, string memberName, bool staticAccess)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1497 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1498 BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1499 (staticAccess ? BindingFlags.Static : BindingFlags.Instance);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1500 foreach (Type t in SelfAndBaseTypes(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1501 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1502 MemberInfo[] members = t.FindMembers(MemberTypes.Property | MemberTypes.Field,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1503 flags, Type.FilterNameIgnoreCase, memberName);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1504 if (members.Length != 0) return members[0];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1505 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1506 return null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1507 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1508
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1509 int FindMethod(Type type, string methodName, bool staticAccess, Expression[] args, out MethodBase method)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1510 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1511 BindingFlags flags = BindingFlags.Public | BindingFlags.DeclaredOnly |
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1512 (staticAccess ? BindingFlags.Static : BindingFlags.Instance);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1513 foreach (Type t in SelfAndBaseTypes(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1514 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1515 MemberInfo[] members = t.FindMembers(MemberTypes.Method,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1516 flags, Type.FilterNameIgnoreCase, methodName);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1517 int count = FindBestMethod(members.Cast<MethodBase>(), args, out method);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1518 if (count != 0) return count;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1519 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1520 method = null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1521 return 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1522 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1523
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1524 int FindIndexer(Type type, Expression[] args, out MethodBase method)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1525 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1526 foreach (Type t in SelfAndBaseTypes(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1527 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1528 MemberInfo[] members = t.GetDefaultMembers();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1529 if (members.Length != 0)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1530 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1531 IEnumerable<MethodBase> methods = members.
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1532 OfType<PropertyInfo>().
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1533 Select(p => (MethodBase)p.GetGetMethod()).
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1534 Where(m => m != null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1535 int count = FindBestMethod(methods, args, out method);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1536 if (count != 0) return count;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1537 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1538 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1539 method = null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1540 return 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1541 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1542
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1543 static IEnumerable<Type> SelfAndBaseTypes(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1544 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1545 if (type.IsInterface)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1546 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1547 List<Type> types = new List<Type>();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1548 AddInterface(types, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1549 return types;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1550 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1551 return SelfAndBaseClasses(type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1552 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1553
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1554 static IEnumerable<Type> SelfAndBaseClasses(Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1555 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1556 while (type != null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1557 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1558 yield return type;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1559 type = type.BaseType;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1560 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1561 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1562
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1563 static void AddInterface(List<Type> types, Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1564 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1565 if (!types.Contains(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1566 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1567 types.Add(type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1568 foreach (Type t in type.GetInterfaces()) AddInterface(types, t);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1569 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1570 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1571
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1572 class MethodData
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1573 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1574 public MethodBase MethodBase;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1575 public ParameterInfo[] Parameters;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1576 public Expression[] Args;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1577 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1578
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1579 int FindBestMethod(IEnumerable<MethodBase> methods, Expression[] args, out MethodBase method)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1580 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1581 MethodData[] applicable = methods.
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1582 Select(m => new MethodData { MethodBase = m, Parameters = m.GetParameters() }).
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1583 Where(m => IsApplicable(m, args)).
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1584 ToArray();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1585 if (applicable.Length > 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1586 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1587 applicable = applicable.
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1588 Where(m => applicable.All(n => m == n || IsBetterThan(args, m, n))).
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1589 ToArray();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1590 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1591 if (applicable.Length == 1)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1592 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1593 MethodData md = applicable[0];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1594 for (int i = 0; i < args.Length; i++) args[i] = md.Args[i];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1595 method = md.MethodBase;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1596 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1597 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1598 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1599 method = null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1600 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1601 return applicable.Length;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1602 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1603
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1604 bool IsApplicable(MethodData method, Expression[] args)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1605 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1606 if (method.Parameters.Length != args.Length) return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1607 Expression[] promotedArgs = new Expression[args.Length];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1608 for (int i = 0; i < args.Length; i++)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1609 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1610 ParameterInfo pi = method.Parameters[i];
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1611 if (pi.IsOut) return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1612 Expression promoted = PromoteExpression(args[i], pi.ParameterType, false);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1613 if (promoted == null) return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1614 promotedArgs[i] = promoted;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1615 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1616 method.Args = promotedArgs;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1617 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1618 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1619
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1620 Expression PromoteExpression(Expression expr, Type type, bool exact)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1621 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1622 if (expr.Type == type) return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1623 if (expr is ConstantExpression)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1624 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1625 ConstantExpression ce = (ConstantExpression)expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1626 if (ce == nullLiteral)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1627 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1628 if (!type.IsValueType || IsNullableType(type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1629 return Expression.Constant(null, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1630 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1631 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1632 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1633 string text;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1634 if (literals.TryGetValue(ce, out text))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1635 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1636 Type target = GetNonNullableType(type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1637 Object value = null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1638 switch (Type.GetTypeCode(ce.Type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1639 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1640 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1641 case TypeCode.UInt32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1642 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1643 case TypeCode.UInt64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1644 value = ParseNumber(text, target);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1645 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1646 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1647 if (target == typeof(decimal)) value = ParseNumber(text, target);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1648 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1649 case TypeCode.String:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1650 value = ParseEnum(text, target);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1651 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1652 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1653 if (value != null)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1654 return Expression.Constant(value, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1655 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1656 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1657 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1658 if (IsCompatibleWith(expr.Type, type))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1659 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1660 if (type.IsValueType || exact) return Expression.Convert(expr, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1661 return expr;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1662 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1663 return null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1664 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1665
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1666 static object ParseNumber(string text, Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1667 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1668 switch (Type.GetTypeCode(GetNonNullableType(type)))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1669 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1670 case TypeCode.SByte:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1671 sbyte sb;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1672 if (sbyte.TryParse(text, out sb)) return sb;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1673 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1674 case TypeCode.Byte:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1675 byte b;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1676 if (byte.TryParse(text, out b)) return b;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1677 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1678 case TypeCode.Int16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1679 short s;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1680 if (short.TryParse(text, out s)) return s;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1681 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1682 case TypeCode.UInt16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1683 ushort us;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1684 if (ushort.TryParse(text, out us)) return us;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1685 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1686 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1687 int i;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1688 if (int.TryParse(text, out i)) return i;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1689 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1690 case TypeCode.UInt32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1691 uint ui;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1692 if (uint.TryParse(text, out ui)) return ui;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1693 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1694 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1695 long l;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1696 if (long.TryParse(text, out l)) return l;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1697 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1698 case TypeCode.UInt64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1699 ulong ul;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1700 if (ulong.TryParse(text, out ul)) return ul;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1701 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1702 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1703 float f;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1704 if (float.TryParse(text, out f)) return f;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1705 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1706 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1707 double d;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1708 if (double.TryParse(text, out d)) return d;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1709 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1710 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1711 decimal e;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1712 if (decimal.TryParse(text, out e)) return e;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1713 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1714 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1715 return null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1716 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1717
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1718 static object ParseEnum(string name, Type type)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1719 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1720 if (type.IsEnum)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1721 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1722 MemberInfo[] memberInfos = type.FindMembers(MemberTypes.Field,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1723 BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1724 Type.FilterNameIgnoreCase, name);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1725 if (memberInfos.Length != 0) return ((FieldInfo)memberInfos[0]).GetValue(null);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1726 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1727 return null;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1728 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1729
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1730 static bool IsCompatibleWith(Type source, Type target)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1731 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1732 if (source == target) return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1733 if (!target.IsValueType) return target.IsAssignableFrom(source);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1734 Type st = GetNonNullableType(source);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1735 Type tt = GetNonNullableType(target);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1736 if (st != source && tt == target) return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1737 TypeCode sc = st.IsEnum ? TypeCode.Object : Type.GetTypeCode(st);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1738 TypeCode tc = tt.IsEnum ? TypeCode.Object : Type.GetTypeCode(tt);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1739 switch (sc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1740 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1741 case TypeCode.SByte:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1742 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1743 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1744 case TypeCode.SByte:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1745 case TypeCode.Int16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1746 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1747 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1748 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1749 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1750 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1751 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1752 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1753 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1754 case TypeCode.Byte:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1755 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1756 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1757 case TypeCode.Byte:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1758 case TypeCode.Int16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1759 case TypeCode.UInt16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1760 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1761 case TypeCode.UInt32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1762 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1763 case TypeCode.UInt64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1764 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1765 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1766 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1767 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1768 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1769 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1770 case TypeCode.Int16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1771 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1772 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1773 case TypeCode.Int16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1774 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1775 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1776 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1777 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1778 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1779 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1780 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1781 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1782 case TypeCode.UInt16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1783 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1784 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1785 case TypeCode.UInt16:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1786 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1787 case TypeCode.UInt32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1788 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1789 case TypeCode.UInt64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1790 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1791 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1792 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1793 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1794 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1795 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1796 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1797 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1798 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1799 case TypeCode.Int32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1800 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1801 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1802 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1803 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1804 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1805 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1806 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1807 case TypeCode.UInt32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1808 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1809 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1810 case TypeCode.UInt32:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1811 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1812 case TypeCode.UInt64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1813 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1814 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1815 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1816 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1817 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1818 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1819 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1820 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1821 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1822 case TypeCode.Int64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1823 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1824 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1825 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1826 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1827 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1828 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1829 case TypeCode.UInt64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1830 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1831 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1832 case TypeCode.UInt64:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1833 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1834 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1835 case TypeCode.Decimal:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1836 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1837 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1838 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1839 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1840 switch (tc)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1841 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1842 case TypeCode.Single:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1843 case TypeCode.Double:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1844 return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1845 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1846 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1847 default:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1848 if (st == tt) return true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1849 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1850 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1851 return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1852 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1853
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1854 static bool IsBetterThan(Expression[] args, MethodData m1, MethodData m2)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1855 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1856 bool better = false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1857 for (int i = 0; i < args.Length; i++)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1858 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1859 int c = CompareConversions(args[i].Type,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1860 m1.Parameters[i].ParameterType,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1861 m2.Parameters[i].ParameterType);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1862 if (c < 0) return false;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1863 if (c > 0) better = true;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1864 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1865 return better;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1866 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1867
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1868 // Return 1 if s -> t1 is a better conversion than s -> t2
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1869 // Return -1 if s -> t2 is a better conversion than s -> t1
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1870 // Return 0 if neither conversion is better
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1871 static int CompareConversions(Type s, Type t1, Type t2)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1872 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1873 if (t1 == t2) return 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1874 if (s == t1) return 1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1875 if (s == t2) return -1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1876 bool t1t2 = IsCompatibleWith(t1, t2);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1877 bool t2t1 = IsCompatibleWith(t2, t1);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1878 if (t1t2 && !t2t1) return 1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1879 if (t2t1 && !t1t2) return -1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1880 if (IsSignedIntegralType(t1) && IsUnsignedIntegralType(t2)) return 1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1881 if (IsSignedIntegralType(t2) && IsUnsignedIntegralType(t1)) return -1;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1882 return 0;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1883 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1884
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1885 Expression GenerateEqual(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1886 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1887 return Expression.Equal(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1888 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1889
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1890 Expression GenerateNotEqual(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1891 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1892 return Expression.NotEqual(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1893 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1894
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1895 Expression GenerateGreaterThan(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1896 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1897 if (left.Type == typeof(string))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1898 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1899 return Expression.GreaterThan(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1900 GenerateStaticMethodCall("Compare", left, right),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1901 Expression.Constant(0)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1902 );
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1903 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1904 return Expression.GreaterThan(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1905 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1906
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1907 Expression GenerateGreaterThanEqual(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1908 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1909 if (left.Type == typeof(string))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1910 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1911 return Expression.GreaterThanOrEqual(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1912 GenerateStaticMethodCall("Compare", left, right),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1913 Expression.Constant(0)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1914 );
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1915 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1916 return Expression.GreaterThanOrEqual(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1917 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1918
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1919 Expression GenerateLessThan(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1920 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1921 if (left.Type == typeof(string))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1922 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1923 return Expression.LessThan(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1924 GenerateStaticMethodCall("Compare", left, right),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1925 Expression.Constant(0)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1926 );
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1927 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1928 return Expression.LessThan(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1929 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1930
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1931 Expression GenerateLessThanEqual(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1932 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1933 if (left.Type == typeof(string))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1934 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1935 return Expression.LessThanOrEqual(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1936 GenerateStaticMethodCall("Compare", left, right),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1937 Expression.Constant(0)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1938 );
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1939 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1940 return Expression.LessThanOrEqual(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1941 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1942
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1943 Expression GenerateAdd(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1944 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1945 if (left.Type == typeof(string) && right.Type == typeof(string))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1946 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1947 return GenerateStaticMethodCall("Concat", left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1948 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1949 return Expression.Add(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1950 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1951
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1952 Expression GenerateSubtract(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1953 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1954 return Expression.Subtract(left, right);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1955 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1956
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1957 Expression GenerateStringConcat(Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1958 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1959 return Expression.Call(
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1960 null,
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1961 typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }),
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1962 new[] { left, right });
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1963 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1964
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1965 MethodInfo GetStaticMethod(string methodName, Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1966 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1967 return left.Type.GetMethod(methodName, new[] { left.Type, right.Type });
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1968 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1969
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1970 Expression GenerateStaticMethodCall(string methodName, Expression left, Expression right)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1971 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1972 return Expression.Call(null, GetStaticMethod(methodName, left, right), new[] { left, right });
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1973 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1974
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1975 void SetTextPos(int pos)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1976 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1977 textPos = pos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1978 ch = textPos < textLen ? text[textPos] : '\0';
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1979 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1980
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1981 void NextChar()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1982 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1983 if (textPos < textLen) textPos++;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1984 ch = textPos < textLen ? text[textPos] : '\0';
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1985 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1986
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1987 void NextToken()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1988 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1989 while (Char.IsWhiteSpace(ch)) NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1990 TokenId t;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1991 int tokenPos = textPos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1992 switch (ch)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1993 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1994 case '!':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1995 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1996 if (ch == '=')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1997 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1998 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
1999 t = TokenId.ExclamationEqual;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2000 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2001 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2002 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2003 t = TokenId.Exclamation;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2004 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2005 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2006 case '%':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2007 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2008 t = TokenId.Percent;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2009 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2010 case '&':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2011 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2012 if (ch == '&')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2013 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2014 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2015 t = TokenId.DoubleAmphersand;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2016 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2017 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2018 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2019 t = TokenId.Amphersand;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2020 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2021 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2022 case '(':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2023 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2024 t = TokenId.OpenParen;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2025 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2026 case ')':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2027 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2028 t = TokenId.CloseParen;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2029 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2030 case '*':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2031 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2032 t = TokenId.Asterisk;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2033 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2034 case '+':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2035 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2036 t = TokenId.Plus;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2037 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2038 case ',':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2039 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2040 t = TokenId.Comma;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2041 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2042 case '-':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2043 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2044 t = TokenId.Minus;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2045 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2046 case '.':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2047 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2048 t = TokenId.Dot;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2049 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2050 case '/':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2051 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2052 t = TokenId.Slash;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2053 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2054 case ':':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2055 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2056 t = TokenId.Colon;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2057 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2058 case '<':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2059 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2060 if (ch == '=')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2061 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2062 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2063 t = TokenId.LessThanEqual;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2064 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2065 else if (ch == '>')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2066 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2067 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2068 t = TokenId.LessGreater;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2069 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2070 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2071 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2072 t = TokenId.LessThan;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2073 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2074 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2075 case '=':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2076 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2077 if (ch == '=')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2078 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2079 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2080 t = TokenId.DoubleEqual;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2081 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2082 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2083 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2084 t = TokenId.Equal;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2085 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2086 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2087 case '>':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2088 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2089 if (ch == '=')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2090 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2091 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2092 t = TokenId.GreaterThanEqual;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2093 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2094 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2095 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2096 t = TokenId.GreaterThan;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2097 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2098 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2099 case '?':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2100 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2101 t = TokenId.Question;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2102 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2103 case '[':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2104 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2105 t = TokenId.OpenBracket;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2106 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2107 case ']':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2108 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2109 t = TokenId.CloseBracket;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2110 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2111 case '|':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2112 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2113 if (ch == '|')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2114 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2115 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2116 t = TokenId.DoubleBar;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2117 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2118 else
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2119 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2120 t = TokenId.Bar;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2121 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2122 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2123 case '"':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2124 case '\'':
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2125 char quote = ch;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2126 do
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2127 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2128 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2129 while (textPos < textLen && ch != quote) NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2130 if (textPos == textLen)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2131 throw ParseError(textPos, Res.UnterminatedStringLiteral);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2132 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2133 } while (ch == quote);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2134 t = TokenId.StringLiteral;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2135 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2136 default:
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2137 if (Char.IsLetter(ch) || ch == '@' || ch == '_')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2138 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2139 do
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2140 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2141 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2142 } while (Char.IsLetterOrDigit(ch) || ch == '_');
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2143 t = TokenId.Identifier;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2144 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2145 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2146 if (Char.IsDigit(ch))
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2147 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2148 t = TokenId.IntegerLiteral;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2149 do
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2150 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2151 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2152 } while (Char.IsDigit(ch));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2153 if (ch == '.')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2154 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2155 t = TokenId.RealLiteral;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2156 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2157 ValidateDigit();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2158 do
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2159 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2160 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2161 } while (Char.IsDigit(ch));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2162 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2163 if (ch == 'E' || ch == 'e')
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2164 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2165 t = TokenId.RealLiteral;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2166 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2167 if (ch == '+' || ch == '-') NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2168 ValidateDigit();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2169 do
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2170 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2171 NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2172 } while (Char.IsDigit(ch));
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2173 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2174 if (ch == 'F' || ch == 'f') NextChar();
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2175 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2176 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2177 if (textPos == textLen)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2178 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2179 t = TokenId.End;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2180 break;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2181 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2182 throw ParseError(textPos, Res.InvalidCharacter, ch);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2183 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2184 token.id = t;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2185 token.text = text.Substring(tokenPos, textPos - tokenPos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2186 token.pos = tokenPos;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2187 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2188
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2189 bool TokenIdentifierIs(string id)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2190 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2191 return token.id == TokenId.Identifier && String.Equals(id, token.text, StringComparison.OrdinalIgnoreCase);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2192 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2193
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2194 string GetIdentifier()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2195 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2196 ValidateToken(TokenId.Identifier, Res.IdentifierExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2197 string id = token.text;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2198 if (id.Length > 1 && id[0] == '@') id = id.Substring(1);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2199 return id;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2200 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2201
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2202 void ValidateDigit()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2203 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2204 if (!Char.IsDigit(ch)) throw ParseError(textPos, Res.DigitExpected);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2205 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2206
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2207 void ValidateToken(TokenId t, string errorMessage)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2208 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2209 if (token.id != t) throw ParseError(errorMessage);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2210 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2211
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2212 void ValidateToken(TokenId t)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2213 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2214 if (token.id != t) throw ParseError(Res.SyntaxError);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2215 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2216
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2217 Exception ParseError(string format, params object[] args)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2218 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2219 return ParseError(token.pos, format, args);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2220 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2221
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2222 Exception ParseError(int pos, string format, params object[] args)
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2223 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2224 return new ParseException(string.Format(System.Globalization.CultureInfo.CurrentCulture, format, args), pos);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2225 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2226
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2227 static Dictionary<string, object> CreateKeywords()
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2228 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2229 Dictionary<string, object> d = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2230 d.Add("true", trueLiteral);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2231 d.Add("false", falseLiteral);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2232 d.Add("null", nullLiteral);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2233 d.Add(keywordIt, keywordIt);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2234 d.Add(keywordIif, keywordIif);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2235 d.Add(keywordNew, keywordNew);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2236 foreach (Type type in predefinedTypes) d.Add(type.Name, type);
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2237 return d;
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2238 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2239 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2240
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2241 static class Res
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2242 {
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2243 public const string DuplicateIdentifier = "The identifier '{0}' was defined more than once";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2244 public const string ExpressionTypeMismatch = "Expression of type '{0}' expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2245 public const string ExpressionExpected = "Expression expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2246 public const string InvalidCharacterLiteral = "Character literal must contain exactly one character";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2247 public const string InvalidIntegerLiteral = "Invalid integer literal '{0}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2248 public const string InvalidRealLiteral = "Invalid real literal '{0}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2249 public const string UnknownIdentifier = "Unknown identifier '{0}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2250 public const string NoItInScope = "No 'it' is in scope";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2251 public const string IifRequiresThreeArgs = "The 'iif' function requires three arguments";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2252 public const string FirstExprMustBeBool = "The first expression must be of type 'Boolean'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2253 public const string BothTypesConvertToOther = "Both of the types '{0}' and '{1}' convert to the other";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2254 public const string NeitherTypeConvertsToOther = "Neither of the types '{0}' and '{1}' converts to the other";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2255 public const string MissingAsClause = "Expression is missing an 'as' clause";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2256 public const string ArgsIncompatibleWithLambda = "Argument list incompatible with lambda expression";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2257 public const string TypeHasNoNullableForm = "Type '{0}' has no nullable form";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2258 public const string NoMatchingConstructor = "No matching constructor in type '{0}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2259 public const string AmbiguousConstructorInvocation = "Ambiguous invocation of '{0}' constructor";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2260 public const string CannotConvertValue = "A value of type '{0}' cannot be converted to type '{1}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2261 public const string NoApplicableMethod = "No applicable method '{0}' exists in type '{1}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2262 public const string MethodsAreInaccessible = "Methods on type '{0}' are not accessible";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2263 public const string MethodIsVoid = "Method '{0}' in type '{1}' does not return a value";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2264 public const string AmbiguousMethodInvocation = "Ambiguous invocation of method '{0}' in type '{1}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2265 public const string UnknownPropertyOrField = "No property or field '{0}' exists in type '{1}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2266 public const string NoApplicableAggregate = "No applicable aggregate method '{0}' exists";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2267 public const string CannotIndexMultiDimArray = "Indexing of multi-dimensional arrays is not supported";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2268 public const string InvalidIndex = "Array index must be an integer expression";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2269 public const string NoApplicableIndexer = "No applicable indexer exists in type '{0}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2270 public const string AmbiguousIndexerInvocation = "Ambiguous invocation of indexer in type '{0}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2271 public const string IncompatibleOperand = "Operator '{0}' incompatible with operand type '{1}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2272 public const string IncompatibleOperands = "Operator '{0}' incompatible with operand types '{1}' and '{2}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2273 public const string UnterminatedStringLiteral = "Unterminated string literal";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2274 public const string InvalidCharacter = "Syntax error '{0}'";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2275 public const string DigitExpected = "Digit expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2276 public const string SyntaxError = "Syntax error";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2277 public const string TokenExpected = "{0} expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2278 public const string ParseExceptionFormat = "{0} (at index {1})";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2279 public const string ColonExpected = "':' expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2280 public const string OpenParenExpected = "'(' expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2281 public const string CloseParenOrOperatorExpected = "')' or operator expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2282 public const string CloseParenOrCommaExpected = "')' or ',' expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2283 public const string DotOrOpenParenExpected = "'.' or '(' expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2284 public const string OpenBracketExpected = "'[' expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2285 public const string CloseBracketOrCommaExpected = "']' or ',' expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2286 public const string IdentifierExpected = "Identifier expected";
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2287 }
060f02cd4591 Initial commit, pre airport work
stevenh7776 stevenhollidge@hotmail.com
parents:
diff changeset
2288 }