Exemplo n.º 1
0
		public override Expr Move(int deltaCol, int deltaRow) {
			Expr[] newEs = new Expr[es.Length];
			for (int i = 0; i < es.Length; i++) {
				newEs[i] = es[i].Move(deltaCol, deltaRow);
			}
			return new FunCall(function, newEs);
		}
Exemplo n.º 2
0
		private Value v; // Up to date if state==Uptodate

		public Formula(Workbook workbook, Expr e) {
			Debug.Assert(workbook != null);
			Debug.Assert(e != null);
			this.workbook = workbook;
			this.e = e;
			this.state = CellState.Uptodate;
		}
Exemplo n.º 3
0
		public static Formula Make(Workbook workbook, Expr e) {
			if (e == null) {
				return null;
			}
			else {
				return new Formula(workbook, e);
			}
		}
Exemplo n.º 4
0
		// Can be copied with sharing if arguments can
		public override Expr CopyTo(int col, int row) {
			bool same = true;
			Expr[] newEs = new Expr[es.Length];
			for (int i = 0; i < es.Length; i++) {
				newEs[i] = es[i].CopyTo(col, row);
				same &= Object.ReferenceEquals(newEs[i], es[i]);
			}
			return same ? this : new FunCall(function, newEs);
		}
Exemplo n.º 5
0
		public override CGExpr PEval(PEnv pEnv, bool hasDynamicControl) {
			CGExpr[] res = PEvalArgs(pEnv, hasDynamicControl);
			// If all args are constant then evaluate else residualize:
			if (AllConstant(res)) {
				Expr[] es = new Expr[res.Length];
				for (int i = 0; i < res.Length; i++) {
					es[i] = Const.Make((res[i] as CGConst).Value);
				}
				// Use the interpretive implementation's applier on a fake sheet 
				// and fake cell coordinates, but constant argument expressions:
				return CGConst.Make(applier(null, es, -1, -1));
			}
			else {
				return Residualize(res);
			}
		}
Exemplo n.º 6
0
		public static Expr Make(String name, Expr[] es) {
			Function function = Function.Get(name);
			if (function == null) {
				function = Function.MakeUnknown(name);
			}
			for (int i = 0; i < es.Length; i++) {
				if (es[i] == null) {
					es[i] = new Error("#SYNTAX");
				}
			}
			if (name == "SPECIALIZE" && es.Length > 1) {
				return new FunCall("SPECIALIZE", Make("CLOSURE", es));
			}
			else {
				return new FunCall(function, es);
			}
		}
Exemplo n.º 7
0
		public override Adjusted<Expr> InsertRowCols(Sheet modSheet,
													 bool thisSheet,
													 int R,
													 int N,
													 int r,
													 bool doRows) {
			Expr[] newEs = new Expr[es.Length];
			int upper = int.MaxValue;
			bool same = true;
			for (int i = 0; i < es.Length; i++) {
				Adjusted<Expr> ae
					= es[i].InsertRowCols(modSheet, thisSheet, R, N, r, doRows);
				upper = Math.Min(upper, ae.upper);
				same = same && ae.same;
				newEs[i] = ae.e;
			}
			return new Adjusted<Expr>(new FunCall(function, newEs), upper, same);
		}
Exemplo n.º 8
0
		private void Exprs1(out Expr[] es) {
			Expr e1, e2;
			List<Expr> elist = new List<Expr>();

			Expr(out e1);
			elist.Add(e1);
			while (la.kind == 30 || la.kind == 31) {
				if (la.kind == 30) {
					Get();
				}
				else {
					Get();
				}
				Expr(out e2);
				elist.Add(e2);
			}
			es = elist.ToArray();
		}
Exemplo n.º 9
0
		private void Application(out Expr e) {
			String s;
			Expr[] es;
			e = null;
			Name(out s);
			Expect(27);
			if (la.kind == 28) {
				Get();
				e = FunCall.Make(s.ToUpper(), new Expr[0]);
			}
			else if (StartOf(4)) {
				Exprs1(out es);
				Expect(28);
				e = FunCall.Make(s.ToUpper(), es);
			}
			else {
				SynErr(39);
			}
		}
Exemplo n.º 10
0
		private void PowFactor(out Expr e) {
			Expr e2;
			Factor(out e);
			while (la.kind == 29) {
				Get();
				Factor(out e2);
				e = FunCall.Make("^", new Expr[] {e, e2});
			}
		}
Exemplo n.º 11
0
		private void Term(out Expr e) {
			Expr e2;
			String op;
			PowFactor(out e);
			while (la.kind == 32 || la.kind == 33) {
				MulOp(out op);
				PowFactor(out e2);
				e = FunCall.Make(op, new Expr[] {e, e2});
			}
		}
Exemplo n.º 12
0
		private void Factor(out Expr e) {
			RARef r1, r2;
			Sheet s1 = null;
			double d;
			bool sheetError = false;
			e = null;
			switch (la.kind) {
				case 1: {
					Application(out e);
					break;
				}
				case 4:
				case 5:
				case 6:
				case 7:
				case 8:
				case 9:
				case 10:
				case 11:
				case 12:
				case 13:
				case 14: {
					if (StartOf(2)) {}
					else {
						Get();
						s1 = workbook[t.val.Substring(0, t.val.Length - 1)];
						if (s1 == null) {
							sheetError = true;
						}
					}
					Raref(out r1);
					if (StartOf(3)) {
						if (sheetError) {
							e = new Error(ErrorValue.refError);
						}
						else {
							e = new CellRef(s1, r1);
						}
					}
					else if (la.kind == 26) {
						Get();
						Raref(out r2);
						if (sheetError) {
							e = new Error(ErrorValue.refError);
						}
						else {
							e = new CellArea(s1, r1, r2);
						}
					}
					else {
						SynErr(37);
					}
					break;
				}
				case 2: {
					Number(out d);
					e = new NumberConst(d);
					break;
				}
				case 18: {
					Get();
					Factor(out e);
					if (e is NumberConst) {
						e = new NumberConst(-((NumberConst)e).value.value);
					}
					else {
						e = FunCall.Make("NEG", new Expr[] {e});
					}

					break;
				}
				case 15: {
					Get();
					e = new TextConst(t.val.Substring(1, t.val.Length - 2));
					break;
				}
				case 27: {
					Get();
					Expr(out e);
					Expect(28);
					break;
				}
				default:
					SynErr(38);
					break;
			}
		}
Exemplo n.º 13
0
		private void LogicalTerm(out Expr e) {
			Expr e2;
			String op;
			e = null;
			Term(out e);
			while (la.kind == 17 || la.kind == 18 || la.kind == 19) {
				AddOp(out op);
				Term(out e2);
				e = FunCall.Make(op, new Expr[] {e, e2});
			}
		}
Exemplo n.º 14
0
		// ----- End of SDF-callable built-in functions -----

		public bool IsVolatile(Expr[] es) {
			// A partial application is volatile if the underlying function is
			if (name == "CLOSURE") {
				if (es.Length > 0 && es[0] is TextConst) {
					String sdfName = (es[0] as TextConst).value.value;
					SdfInfo sdfInfo = SdfManager.GetInfo(sdfName);
					return sdfInfo != null && sdfInfo.IsVolatile;
				}
				else {
					return false;
				}
			}
			else {
				return isVolatile;
			}
		}
Exemplo n.º 15
0
		private static Value Closure(Sheet sheet, Expr[] es, int col, int row) {
			// First argument may be a (constant) function name or a FunctionValue
			if (es.Length < 1) {
				return ErrorValue.argCountError;
			}
			int argCount = es.Length - 1;
			Value[] arguments = new Value[argCount];
			for (int i = 1; i < es.Length; i++) {
				Value vi = es[i].Eval(sheet, col, row);
				if (vi == null) {
					return ErrorValue.argTypeError;
				}
				arguments[i - 1] = vi;
			}
			if (es[0] is TextConst) {
				String name = (es[0] as TextConst).value.value;
				SdfInfo sdfInfo = SdfManager.GetInfo(name);
				if (sdfInfo == null) {
					return ErrorValue.nameError;
				}
				if (argCount != 0 && argCount != sdfInfo.arity) {
					return ErrorValue.argCountError;
				}
				return new FunctionValue(sdfInfo, arguments);
			}
			else {
				Value v0 = es[0].Eval(sheet, col, row);
				if (v0 is FunctionValue) // Further application of a partial application 
				{
					return (v0 as FunctionValue).FurtherApply(arguments);
				}
				else if (v0 is ErrorValue) {
					return v0;
				}
				else {
					return ErrorValue.argTypeError;
				}
			}
		}
Exemplo n.º 16
0
		// Auxiliary for EXTERN and EXTERNVOLATILE
		private static Value CallExtern(Sheet sheet, Expr[] es, int col, int row) {
			if (es.Length < 1) {
				return ErrorValue.argCountError;
			}
			TextConst nameAndSignatureConst = es[0] as TextConst;
			if (nameAndSignatureConst == null) {
				return ErrorValue.argTypeError;
			}
			try {
				// This retrieves the method from cache, or creates it:
				ExternalFunction ef = ExternalFunction.Make(nameAndSignatureConst.value.value);
				Value[] values = new Value[es.Length - 1];
				for (int i = 0; i < values.Length; i++) {
					values[i] = es[i + 1].Eval(sheet, col, row);
				}
				return ef.Call(values);
			}
			catch (TargetInvocationException exn) // From external method
			{
				return ErrorValue.Make(exn.InnerException.Message);
			}
			catch (Exception exn) // Covers a multitude of sins
			{
				return ErrorValue.Make("#EXTERN: " + exn.Message);
			}
		}
Exemplo n.º 17
0
		private FunCall(Function function, Expr[] es) {
			// Assert: function != null, all es[i] != null
			this.function = function;
			this.es = es;
		}
Exemplo n.º 18
0
		public Value Apply(Sheet sheet, Expr[] es, int col, int row) {
			// Arity is checked in the SdfInfo.CallN methods
			switch (es.Length) {
				case 0:
					return Call0();
				case 1:
					return Call1(es[0].Eval(sheet, col, row));
				case 2:
					return Call2(es[0].Eval(sheet, col, row), es[1].Eval(sheet, col, row));
				case 3:
					return Call3(es[0].Eval(sheet, col, row),
								 es[1].Eval(sheet, col, row),
								 es[2].Eval(sheet, col, row));
				case 4:
					return Call4(es[0].Eval(sheet, col, row),
								 es[1].Eval(sheet, col, row),
								 es[2].Eval(sheet, col, row),
								 es[3].Eval(sheet, col, row));
				case 5:
					return Call5(es[0].Eval(sheet, col, row),
								 es[1].Eval(sheet, col, row),
								 es[2].Eval(sheet, col, row),
								 es[3].Eval(sheet, col, row),
								 es[4].Eval(sheet, col, row));
				case 6:
					return Call6(es[0].Eval(sheet, col, row),
								 es[1].Eval(sheet, col, row),
								 es[2].Eval(sheet, col, row),
								 es[3].Eval(sheet, col, row),
								 es[4].Eval(sheet, col, row),
								 es[5].Eval(sheet, col, row));
				case 7:
					return Call7(es[0].Eval(sheet, col, row),
								 es[1].Eval(sheet, col, row),
								 es[2].Eval(sheet, col, row),
								 es[3].Eval(sheet, col, row),
								 es[4].Eval(sheet, col, row),
								 es[5].Eval(sheet, col, row),
								 es[6].Eval(sheet, col, row));
				case 8:
					return Call8(es[0].Eval(sheet, col, row),
								 es[1].Eval(sheet, col, row),
								 es[2].Eval(sheet, col, row),
								 es[3].Eval(sheet, col, row),
								 es[4].Eval(sheet, col, row),
								 es[5].Eval(sheet, col, row),
								 es[6].Eval(sheet, col, row),
								 es[7].Eval(sheet, col, row));
				case 9:
					return Call9(es[0].Eval(sheet, col, row),
								 es[1].Eval(sheet, col, row),
								 es[2].Eval(sheet, col, row),
								 es[3].Eval(sheet, col, row),
								 es[4].Eval(sheet, col, row),
								 es[5].Eval(sheet, col, row),
								 es[6].Eval(sheet, col, row),
								 es[7].Eval(sheet, col, row),
								 es[8].Eval(sheet, col, row));
				default:
					return ErrorValue.Make("#FUNERR: Too many arguments");
			}
		}
Exemplo n.º 19
0
		private void Expr(out Expr e) {
			Expr e2;
			String op;
			e = null;
			LogicalTerm(out e);
			while (StartOf(1)) {
				LogicalOp(out op);
				LogicalTerm(out e2);
				e = FunCall.Make(op, new Expr[] {e, e2});
			}
		}
Exemplo n.º 20
0
		public override void InsertRowCols(Dictionary<Expr, Adjusted<Expr>> adjusted,
										   Sheet modSheet,
										   bool thisSheet,
										   int R,
										   int N,
										   int r,
										   bool doRows) {
			Adjusted<Expr> ae;
			if (adjusted.ContainsKey(e) && r < adjusted[e].upper) {
				// There is a valid cached adjusted expression
				ae = adjusted[e];
			}
			else {
				// Compute a new adjusted expression and insert into the cache
				ae = e.InsertRowCols(modSheet, thisSheet, R, N, r, doRows);
				Console.WriteLine("Making new adjusted at rowcol " + r
								  + "; upper = " + ae.upper);
				if (ae.same) { // For better sharing, reuse unadjusted e if same
					ae = new Adjusted<Expr>(e, ae.upper, ae.same);
					Console.WriteLine("Reusing expression");
				}
				adjusted[e] = ae;
			}
			Debug.Assert(r < ae.upper, "Formula.InsertRowCols");
			e = ae.e;
		}
Exemplo n.º 21
0
		// Evaluate expression array
		private static Value[] Eval(Expr[] es, Sheet sheet, int col, int row) {
			Value[] vs = new Value[es.Length];
			for (int i = 0; i < es.Length; i++) {
				vs[i] = es[i].Eval(sheet, col, row);
			}
			return vs;
		}