internal override void EmitIl(ILGenerator il, CompilerState state) { if (_opCode != OpCodes.Call) { il.Emit(_opCode); } else { il.Emit(_opCode, _mathPowInfo); } state.StackHeight--; }
/// <summary> /// /// </summary> /// <param name="state"></param> /// <param name="arguments"></param> /// <returns></returns> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> public override object?Evaluate(CompilerState state, FieldSyntax field) { if (field is null) { throw new ArgumentNullException(nameof(field)); } if (field.Name is null) { throw new ArgumentException("Field name cannot be empty", nameof(field)); } var fieldArgument = EngineInstruction.Evaluate(state, field.Value); return(new ObjectField(field, field.Name.Value, fieldArgument)); }
private Expression Analyze(ParseTree tree, CompilerState state) { if (tree == null) { throw new ArgumentNullException("tree"); } if (tree.Status != ParseTreeStatus.Parsed) { throw new ArgumentException("Cannot build expression on incomplete tree"); } var root = tree.Root; return(Analyze(root, state)); }
Value evaluateArray(Variable variable, Value value) { Array yArray; var list = new List <Value>(); var xValue = variable.Value; var variableName = VAR_ANONYMOUS + CompilerState.ObjectID(); if (xValue.IsArray) { var xArray = (Array)xValue.SourceArray; Variable anonymousVariable; if (value.IsArray) { yArray = (Array)value.SourceArray; var minLength = Math.Min(xArray.Length, yArray.Length); for (var i = 0; i < minLength; i++) { var xItem = xArray[i]; var yItem = yArray[i]; Regions.Current.CreateVariable(variableName); anonymousVariable = new Variable(variableName) { Value = xItem }; list.Add(evaluate(anonymousVariable, yItem)); } Regions.Current.Remove(variableName); return(new Array(list)); } anonymousVariable = new Variable(variableName); foreach (var item in xArray) { anonymousVariable.Value = item.Value; list.Add(evaluate(anonymousVariable, value)); } Regions.Current.Remove(variableName); return(new Array(list)); } if (value.IsArray) { yArray = (Array)value.SourceArray; list.AddRange(yArray.Select(i => evaluate(variable, i.Value))); return(new Array(list)); } return(evaluate(variable, variable)); }
public string GetFuncTypeName(CompilerState State, TypeOfFunction FuncType) { var FuncCh = FuncType.Children; var Rec = State.Language.Root.GetObject <CallingConventionRecognizer>(); var Mod = Rec.GetCallingConventionName(FuncType.CallConv); var Out = Mod + " "; if (FuncCh.Length == 1) { Out += "void"; } else { for (var i = 1; i < FuncCh.Length; i++) { Out += State.GenerateName(FuncCh[i].TypeOfSelf); if (i < FuncCh.Length - 1) { Out += ", "; } } } Out += " -> "; var RetType = FuncCh[0]; if (RetType.RealId is TupleType) { var Tuple = RetType.RealId as TupleType; var Members = Tuple.StructuredScope.IdentifierList; for (var i = 0; i < Members.Count; i++) { Out += State.GenerateName(Members[i].TypeOfSelf); if (i < Members.Count - 1) { Out += ", "; } } } else { Out += State.GenerateName(RetType); } return(Out); }
private Expression PredefinedAtom_IfNull(ParseTreeNode root, CompilerState state) { root.RequireChildren(2); var arg1Node = root.RequireChild(null, 1, 0, 0); var argument = state.ParentRuntime.Analyze(arg1Node, state); var isnullableType = argument.IsNullableType(); var arg2Node = root.RequireChild(null, 1, 0, 1); var ifnull = state.ParentRuntime.Analyze(arg2Node, state); if (!ExpressionTreeExtensions.TryAdjustVoid(ref argument, ref ifnull)) { throw new CompilationException("Could not adjust void blocks", root); } if (argument.IsVoid()) { return(ifnull); } ifnull = ExpressionTreeExtensions.AdjustReturnType(arg2Node, ifnull, argument.Type.GetUnderlyingType()); Expression result; if (argument.Type.IsValueType) { result = isnullableType ? Expression.Condition(Expression.Field(argument, "HasValue"), Expression.Field(argument, "Value"), ifnull) : argument; } else { // now only reference types remaining var constantExpression = argument as ConstantExpression; if (constantExpression != null) { result = ReferenceEquals(constantExpression.Value, null) ? ifnull : argument; } else { result = Expression.Condition(Expression.Equal(argument, Expression.Constant(null)), ifnull, argument); } } return(result.IsVoid() ? result : result.RemoveNullability()); }
public void ProvideInput(long input) { if (_state != CompilerState.PausedWaitingForInput) { throw new InvalidOperationException("not expecting input at this time"); } Opcode opcode = new Opcode(GetAndExtendAsNecessary(_currentinstruction)); long location = _currentinstruction + 1; if (opcode.Modes[0] == ParameterMode.Position) { location = GetAndExtendAsNecessary(location); } SetAndExtendAsNecessary(location, input); _currentinstruction += opcode.Jump; _state = CompilerState.Poised; }
private Expression BuildBetweenExpression(ParseTreeNode root, CompilerState state) { root.RequireChildren(6); var variableNode = root.ChildNodes[0]; var notOpt = root.RequireChild("notOpt", 1); root.RequireChild("between", 2); root.RequireChild("and", 4); var argument = Analyze(variableNode, state).RemoveNullability(); var leftNode = root.ChildNodes[3]; var leftExpr = Analyze(leftNode, state); leftExpr.RequireNonVoid(leftNode); leftExpr = ExpressionTreeExtensions.AdjustReturnType(leftNode, leftExpr, argument.Type); var rightNode = root.ChildNodes[5]; var rightExpr = Analyze(rightNode, state); rightExpr.RequireNonVoid(rightNode); rightExpr = ExpressionTreeExtensions.AdjustReturnType(rightNode, rightExpr, argument.Type); Expression lower, upper; if (argument.IsString()) { lower = ConstantHelper.TryEvalConst(leftNode, PrepareStringComparison(leftNode, leftExpr, argument), Expression.Constant(0), ExpressionType.LessThanOrEqual); upper = ConstantHelper.TryEvalConst(rightNode, PrepareStringComparison(rightNode, rightExpr, argument), Expression.Constant(0), ExpressionType.GreaterThanOrEqual); } else { lower = ConstantHelper.TryEvalConst(leftNode, argument, leftExpr, ExpressionType.GreaterThanOrEqual); upper = ConstantHelper.TryEvalConst(rightNode, argument, rightExpr, ExpressionType.LessThanOrEqual); } var result = ConstantHelper.TryEvalConst(root, lower, upper, ExpressionType.AndAlso); if (notOpt.ChildNodes.Count > 0) { result = ConstantHelper.TryEvalConst(root, result, ExpressionType.Not); } return(result); }
private CompilerState CompileNode(CompilerState previousState) { switch (previousState.Node.Kind) { case NodeKind.Program: return(CompileProgramNode(previousState)); case NodeKind.Let: return(CompileLetStatement(previousState)); case NodeKind.Return: return(CompileReturnStatement(previousState)); default: return(CompileExpression(previousState)); } }
private CompilerState CompileStatementExpression(CompilerState previousState) { var expressionState = CompileExpression(previousState); if (expressionState.Errors.Count > 0) { return(expressionState); } if (expressionState.CurrentScope.CurrentInstruction.Opcode == (byte)Opcode.Name.Pop) { // We want to keep defined values on the stack expressionState = RemoveLastPopInstruction(expressionState); } return(expressionState); }
List <LocalVariableInfo> EmitRedirectionDescendants(CompilerState state, Node node) { if (state == null) { throw new Exception(); } if (node == null) { throw new Exception(); } List <LocalVariableInfo> output = new List <LocalVariableInfo>(); for (Int32 i = 0; i < node.Children.Count - 1; ++i) { output.Add(Emit(state, node.Children[i])); } foreach (Object arg in node.Arguments) { if (arg is String) { LocalVariableInfo local = state.Generator.DeclareLocal(typeof(String)); state.Generator.Emit(OpCodes.Ldstr, (String)arg); StoreLocalVariable(state, local); output.Add(local); } else if (arg.GetType().IsEnum == true) { LocalVariableInfo local = state.Generator.DeclareLocal(arg.GetType()); state.Generator.Emit(OpCodes.Ldc_I4, (Int32)arg); StoreLocalVariable(state, local); output.Add(local); } else { throw new Exception(); } } return(output); }
private CompilerState CompileReturnStatement(CompilerState previousState) { var statement = (Statement)previousState.Node; // Top level return statement with no value to return if (statement.Expression == default(Expression)) { // Effectively pushes Null object onto and from the stack, so // we won't end up with no value as the vm.Run() result var returnState = Emit((byte)Opcode.Name.Return, new List <int>(), previousState); return(Emit((byte)Opcode.Name.Pop, new List <int>(), returnState)); } var expressionState = CompileStatementExpression(previousState); return(Emit((byte)Opcode.Name.ReturnValue, new List <int>(), expressionState)); }
LocalVariableInfo EmitArithmeticOperator(CompilerState state, OpCode msilcode, LocalVariableInfo lhs, LocalVariableInfo rhs) { if (state == null) { throw new Exception(); } if (lhs == null) { throw new Exception(); } if (rhs == null) { throw new Exception(); } if (msilcode == OpCodes.Div) { CheckIfZero(state, rhs); } LocalVariableInfo result; if (lhs.LocalType == typeof(Int32) && rhs.LocalType == typeof(Int32)) { result = state.Generator.DeclareLocal(typeof(Int32)); LoadLocalVariable(state, lhs); LoadLocalVariable(state, rhs); } else { result = state.Generator.DeclareLocal(typeof(Single)); LoadLocalVariable(state, lhs); state.Generator.Emit(OpCodes.Conv_R4); LoadLocalVariable(state, rhs); state.Generator.Emit(OpCodes.Conv_R4); } state.Generator.Emit(msilcode); StoreLocalVariable(state, result); return(result); }
private Expression PredefinedAtom_SetContains(ParseTreeNode root, CompilerState state) { root.RequireChildren(2); var arg1Node = root.RequireChild(null, 1, 0, 0); var hashset = state.ParentRuntime.Analyze(arg1Node, state); hashset.RequireNonVoid(arg1Node); if (hashset.Type.IsValueType) { throw new CompilationException("Set must be of reference type", arg1Node); } if (hashset is ConstantExpression) { throw new CompilationException("Set must not be a constant expression", arg1Node); } var arg2Node = root.RequireChild(null, 1, 0, 1); var element = state.ParentRuntime.Analyze(arg2Node, state); var methods = hashset.Type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.FlattenHierarchy); foreach (var method in methods) { if (method.Name.Equals("Contains")) { var methodArgs = method.GetParameters(); if (methodArgs.Length == 1 && methodArgs[0].ParameterType != typeof(object)) { Expression adjusted; if (ExpressionTreeExtensions.TryAdjustReturnType(arg2Node, element, methodArgs[0].ParameterType, out adjusted)) { return(Expression.Condition( Expression.ReferenceEqual(hashset, Expression.Constant(null)), Expression.Constant(false, typeof(bool)), Expression.Call(hashset, method, adjusted))); } } } } throw new CompilationException( "Could not find a public instance method 'Contains' to match element type " + element.Type.FullName, arg1Node); }
private CompilerState CompileProgramNode(CompilerState previousState) { var newState = Factory.CompilerState() .Assign(previousState) .Create(); var program = (Program)newState.Node; if (program.Errors.Count > 0) { return(Factory.CompilerState() .Assign(newState) .Errors(program.Errors) .Create()); } return(CompileStatements(program.Statements, previousState)); }
public SimpleRecResult GenerateName(CompilerState State, Identifier Id, ref string Out) { if (Id is TypeOfFunction) { var FuncType = Id as TypeOfFunction; Out = "static " + GetFuncTypeName(State, FuncType); return(SimpleRecResult.Succeeded); } else if (Id is NonstaticFunctionType) { var NFuncType = Id as NonstaticFunctionType; var FuncType = NFuncType.Child.RealId as TypeOfFunction; Out = GetFuncTypeName(State, FuncType); return(SimpleRecResult.Succeeded); } return(SimpleRecResult.Unknown); }
private static Expression PredefinedAtom_Cast(ParseTreeNode root, CompilerState state) { root.RequireChildren(2); var arg1Node = root.RequireChild(null, 1, 0, 0); var value = state.ParentRuntime.Analyze(arg1Node, state).RemoveNullability(); var arg2Node = root.RequireChild("string", 1, 0, 1); var targetType = RequireSystemType(arg2Node); if (value.IsVoid()) { return(ExpressionTreeExtensions.GetDefaultExpression(targetType)); } // bluntly attempt to convert the type; will throw if types are not compatible return(ConstantHelper.TryEvalConst(root, value, ExpressionType.Convert, targetType)); }
public bool GetParameters(CompilerState State, CodeString Code, out CodeString Function, out CodeString Parameters) { var Pos = FindParamPosition(State, Code.String); if (Pos != -1) { Function = Code.Substring(0, Pos).Trim(); var Handlers = State.Language.GlobalHandlers; Parameters = Code.Substring(Pos).TrimOneBracket(Handlers); } else { Function = Code; Parameters = Code.Substring(Code.Length); } return(true); }
public static void AddBibliography(CompilerState state, [Argument(Name = "bibliography", ProposalProvider = typeof(BibliographyFileProposalProvider))] Argument <string> bibliographyPath) { if (state.Document.Citations == null) { return; } try { var text = state.Context.ResourceSet.RelativeResource(bibliographyPath.Value).GetContentAsString(); var bibEntries = BibParser.Parse(text, out var _); state.Document.Citations.AddRange(bibEntries.Select(e => e.ToCitation())); } catch (Exception ex) { throw new CompilerException(bibliographyPath.Source, $"Could not find resource '{bibliographyPath.Value}'", ex); } }
private CompilerState CompileArrayExpression(Expression expression, CompilerState previousState) { var arrayExpression = (ArrayExpression)expression; var arrayExpressionState = previousState; foreach (var element in arrayExpression.Elements) { arrayExpressionState = CompileExpressionInner(element, previousState); if (arrayExpressionState.Errors.Count > 0) { return(arrayExpressionState); } } return(Emit((byte)Opcode.Name.Array, new List <int> { arrayExpression.Elements.Count }, arrayExpressionState)); }
private CompilerState CompileExpressionInner(Expression expression, CompilerState previousState) { switch (expression.Kind) { case ExpressionKind.Integer: return(CompileIntegerExpression(expression, previousState)); case ExpressionKind.Boolean: return(CompileBooleanExpression(expression, previousState)); case ExpressionKind.String: return(CompileStringExpression(expression, previousState)); case ExpressionKind.Identifier: return(CompileIdentifierExpression(expression, previousState)); case ExpressionKind.Prefix: return(CompilePrefixExpression(expression, previousState)); case ExpressionKind.Infix: return(CompileInfixExpression(expression, previousState)); case ExpressionKind.IfElse: return(CompileIfElseExpression(expression, previousState)); case ExpressionKind.Array: return(CompileArrayExpression(expression, previousState)); case ExpressionKind.Hash: return(CompileHashExpression(expression, previousState)); case ExpressionKind.Index: return(CompileIndexExpression(expression, previousState)); case ExpressionKind.Function: return(CompileFunctionExpression(expression, previousState)); case ExpressionKind.Call: return(CompileCallExpression(expression, previousState)); } return(previousState); }
public static void DefineColor(CompilerState state, Argument <string> colorName, Argument <string> value) { if (string.IsNullOrWhiteSpace(colorName.Value)) { state.Issues.Add(value.Source, CompilerIssueType.Warning, "Invalid name for color."); } var color = Color.FromCode(value.Value); if (color != null) { var customColors = ColorVariables.CustomColors.Get(state.Document) ?? throw new InvalidOperationException(); customColors[colorName.Value] = color.Value; } else { state.Issues.Add(value.Source, CompilerIssueType.Warning, $"Could not create color from '{value.Value}'."); } }
private static void SetFixedBlock(CompilerState state, Paragraph content, FixedPosition position) { var block = new FixedBlock(content) { Position = position }; for (int i = 0; i < state.Document.PageItems.Count; i++) { var item = state.Document.PageItems[i]; if (item is FixedBlock fix && fix.Position == position) { state.Document.PageItems.RemoveAt(i); break; } } state.Document.PageItems.Add(block); }
LocalVariableInfo EmitLogicalOperator(CompilerState state, Operator @operator, LocalVariableInfo lhs, LocalVariableInfo rhs) { if (state == null) { throw new Exception(); } if (lhs == null) { throw new Exception(); } if (rhs == null) { throw new Exception(); } LocalVariableInfo result = state.Generator.DeclareLocal(typeof(Int32)); PushAsBoolean(state, lhs); PushAsBoolean(state, rhs); switch (@operator) { case Operator.LogicalAnd: state.Generator.Emit(OpCodes.And); StoreLocalVariable(state, result); break; case Operator.LogicalOr: state.Generator.Emit(OpCodes.Or); StoreLocalVariable(state, result); break; case Operator.LogicalXor: state.Generator.Emit(OpCodes.Xor); StoreLocalVariable(state, result); break; default: throw new Exception(); } return(result); }
private Exp MakeSpecialFunction(CompilerState state, Type type, string constant) { if (state == null) { throw new Exception(); } if (type == null) { throw new Exception(); } if (constant == null) { throw new Exception(); } Dictionary <string, MethodInfo> methodmap; if (type == typeof(Triggers.Const)) { methodmap = m_constfunctionmethods; } else if (type == typeof(Triggers.GetHitVar)) { methodmap = m_gethitvarmethods; } else { throw new Exception(); } MethodInfo method; if (methodmap.TryGetValue(constant, out method) == false) { throw new Exception(); } var args = new List <Exp> { state.FunctionState, state.ErrorVariable }; return(Exp.Call(null, method, args)); }
public EvaluationCallback Create(Node node) { var method = new DynamicMethod(string.Empty, typeof(Number), new[] { typeof(Character) }, typeof(ILCompiler), true); var compilerstate = new CompilerState { Generator = method.GetILGenerator() }; compilerstate.FunctionState = compilerstate.Generator.DeclareLocal(typeof(Character)); compilerstate.ErrorLabel = compilerstate.Generator.DefineLabel(); compilerstate.ErrorVariable = compilerstate.Generator.DeclareLocal(typeof(bool)); compilerstate.Generator.Emit(OpCodes.Ldarg, 0); StoreLocalVariable(compilerstate, compilerstate.FunctionState); var result = Emit(compilerstate, node); if (result.LocalType == typeof(int)) { LoadLocalVariable(compilerstate, result); compilerstate.Generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new[] { typeof(int) })); } else if (result.LocalType == typeof(float)) { LoadLocalVariable(compilerstate, result); compilerstate.Generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new[] { typeof(float) })); } else { throw new Exception(); } compilerstate.Generator.Emit(OpCodes.Ret); compilerstate.Generator.MarkLabel(compilerstate.ErrorLabel); LoadLocalVariable(compilerstate, compilerstate.Generator.DeclareLocal(typeof(Number))); compilerstate.Generator.Emit(OpCodes.Ret); var callback = (EvaluationCallback)method.CreateDelegate(typeof(EvaluationCallback)); return(callback); }
private Exp MakeMethod(CompilerState state, MethodInfo method, IList <Exp> args) { if (state == null) { throw new Exception(); } if (method == null) { throw new Exception(); } if (args == null) { throw new Exception(); } var parameters = method.GetParameters(); for (var i = 0; i != args.Count; ++i) { if (parameters[i].ParameterType == typeof(float) && args[i].Type != typeof(float)) { args[i] = ToFloat(args[i]); } if (parameters[i].ParameterType == typeof(double) && args[i].Type != typeof(double)) { args[i] = ToDouble(args[i]); } } var result = Exp.Call(null, method, args); if (result.Type == typeof(bool)) { return(ToInteger(result)); } if (result.Type == typeof(double)) { return(ToFloat(result)); } return(result); }
private CompilerState CompileHashExpression(Expression expression, CompilerState previousState) { var hashExpression = (HashExpression)expression; var hashExpressionState = previousState; for (var i = 0; i < hashExpression.Keys.Count; i++) { hashExpressionState = CompileExpressionInner(hashExpression.Keys[i], hashExpressionState); hashExpressionState = CompileExpressionInner(hashExpression.Values[i], hashExpressionState); if (hashExpressionState.Errors.Count > 0) { return(hashExpressionState); } } return(Emit((byte)Opcode.Name.Hash, new List <int> { hashExpression.Keys.Count }, hashExpressionState)); }
public override object?Execute(CompilerState state, Argument[] arguments) { var parentBlock = state.Blocks.Peek(1); var creator = new ObjectCreator(Origin, state); // if a type specification exists if (parentBlock.Objects.Count == 1 && typeElement != null) { parentBlock.Objects.Clear(); creator.TypeElement = typeElement; creator.TypeName = typeElement.Content; } else if (parentBlock.Objects.Count > 0) { throw new Exception(); } creator.Fields.AddRange(arguments.Select(e => e.Value).Cast <ObjectField>()); return(creator); }
public override Verb CreateVerb(string[] tokens) { Color(position, tokens[1].Length, KeyWords); Color(1, Structures); var index = position + length; var superName = ""; Parameters superParameters = null; if (inheritanceParser.Scan(source, index)) { superName = inheritanceParser.VariableName; superParameters = inheritanceParser.Parameters; index = inheritanceParser.Result.Position; } var traits = new List <string>(); if (doesParser.Scan(source, index)) { traits = doesParser.Traits; index = doesParser.Result.Position; } Block objectBlock; try { InClassDefinition = true; ParseBlock(source, index, "'}'").Assign(out objectBlock, out index); } finally { InClassDefinition = false; } var builder = new Class(new Parameters(), objectBlock, GetStaticBlock(), superName, traits.ToArray(), superParameters, false); result.Value = builder; overridePosition = index; return(new CreateObject(VAR_ANONYMOUS + CompilerState.ObjectID(), builder, false, Protected)); }
public EvaluationCallback Create(Node node) { DynamicMethod method = new DynamicMethod(String.Empty, typeof(Number), new Type[] { typeof(Object) }, typeof(Compiler), true); CompilerState compilerstate = new CompilerState(); compilerstate.Generator = method.GetILGenerator(); compilerstate.FunctionState = compilerstate.Generator.DeclareLocal(typeof(Object)); compilerstate.ErrorLabel = compilerstate.Generator.DefineLabel(); compilerstate.ErrorVariable = compilerstate.Generator.DeclareLocal(typeof(Boolean)); compilerstate.Generator.Emit(OpCodes.Ldarg, 0); StoreLocalVariable(compilerstate, compilerstate.FunctionState); LocalVariableInfo result = Emit(compilerstate, node); if (result.LocalType == typeof(Int32)) { LoadLocalVariable(compilerstate, result); compilerstate.Generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Int32) })); } else if (result.LocalType == typeof(Single)) { LoadLocalVariable(compilerstate, result); compilerstate.Generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Single) })); } else { throw new Exception(); } compilerstate.Generator.Emit(OpCodes.Ret); compilerstate.Generator.MarkLabel(compilerstate.ErrorLabel); LoadLocalVariable(compilerstate, compilerstate.Generator.DeclareLocal(typeof(Number))); compilerstate.Generator.Emit(OpCodes.Ret); EvaluationCallback callback = (EvaluationCallback)method.CreateDelegate(typeof(EvaluationCallback)); return(callback); }
public EvaluationCallback Create(Node node) { DynamicMethod method = new DynamicMethod(String.Empty, typeof(Number), new Type[] { typeof(Object) }, typeof(Compiler), true); CompilerState compilerstate = new CompilerState(); compilerstate.Generator = method.GetILGenerator(); compilerstate.FunctionState = compilerstate.Generator.DeclareLocal(typeof(Object)); compilerstate.ErrorLabel = compilerstate.Generator.DefineLabel(); compilerstate.ErrorVariable = compilerstate.Generator.DeclareLocal(typeof(Boolean)); compilerstate.Generator.Emit(OpCodes.Ldarg, 0); StoreLocalVariable(compilerstate, compilerstate.FunctionState); LocalVariableInfo result = Emit(compilerstate, node); if (result.LocalType == typeof(Int32)) { LoadLocalVariable(compilerstate, result); compilerstate.Generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Int32) })); } else if (result.LocalType == typeof(Single)) { LoadLocalVariable(compilerstate, result); compilerstate.Generator.Emit(OpCodes.Newobj, typeof(Number).GetConstructor(new Type[] { typeof(Single) })); } else { throw new Exception(); } compilerstate.Generator.Emit(OpCodes.Ret); compilerstate.Generator.MarkLabel(compilerstate.ErrorLabel); LoadLocalVariable(compilerstate, compilerstate.Generator.DeclareLocal(typeof(Number))); compilerstate.Generator.Emit(OpCodes.Ret); EvaluationCallback callback = (EvaluationCallback)method.CreateDelegate(typeof(EvaluationCallback)); return callback; }
LocalVariableInfo EmitComparsionOperator(CompilerState state, Operator @operator, LocalVariableInfo lhs, LocalVariableInfo rhs) { if (state == null) throw new Exception(); if (lhs == null) throw new Exception(); if (rhs == null) throw new Exception(); LocalVariableInfo result = state.Generator.DeclareLocal(typeof(Int32)); if (lhs.LocalType == typeof(Int32) && rhs.LocalType == typeof(Int32)) { LoadLocalVariable(state, lhs); LoadLocalVariable(state, rhs); } else { LoadLocalVariable(state, lhs); state.Generator.Emit(OpCodes.Conv_R4); LoadLocalVariable(state, rhs); state.Generator.Emit(OpCodes.Conv_R4); } switch (@operator) { case Operator.Equals: state.Generator.Emit(OpCodes.Ceq); StoreLocalVariable(state, result); break; case Operator.NotEquals: state.Generator.Emit(OpCodes.Ceq); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.Emit(OpCodes.Ceq); StoreLocalVariable(state, result); break; case Operator.Lesser: state.Generator.Emit(OpCodes.Clt); StoreLocalVariable(state, result); break; case Operator.LesserEquals: state.Generator.Emit(OpCodes.Cgt); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.Emit(OpCodes.Ceq); StoreLocalVariable(state, result); break; case Operator.Greater: state.Generator.Emit(OpCodes.Cgt); StoreLocalVariable(state, result); break; case Operator.GreaterEquals: state.Generator.Emit(OpCodes.Clt); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.Emit(OpCodes.Ceq); StoreLocalVariable(state, result); break; default: throw new Exception(); } return result; }
LocalVariableInfo EmitAssignmentOperator(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); Evaluation.Tokenizing.OperatorData data = node.Token.Data as Evaluation.Tokenizing.OperatorData; if (data == null || data.Operator != Operator.Assignment) throw new Exception(); if (node.Children.Count != 2) throw new Exception(); Evaluation.Tokenizing.CustomFunctionData vardata = node.Children[0].Token.Data as Evaluation.Tokenizing.CustomFunctionData; if (vardata == null) throw new Exception(); if (node.Children[0].Children.Count != 1) throw new Exception(); LocalVariableInfo index = Emit(state, node.Children[0].Children[0]); LocalVariableInfo value = Emit(state, node.Children[1]); List<LocalVariableInfo> args = new List<LocalVariableInfo>() { state.FunctionState, index, value }; if (vardata.Type == typeof(Triggers.Var)) { return EmitMethod(state, typeof(SpecialFunctions).GetMethod("Assignment_Var"), args); } if (vardata.Type == typeof(Triggers.FVar)) { return EmitMethod(state, typeof(SpecialFunctions).GetMethod("Assignment_FVar"), args); } if (vardata.Type == typeof(Triggers.SysVar)) { return EmitMethod(state, typeof(SpecialFunctions).GetMethod("Assignment_SysVar"), args); } if (vardata.Type == typeof(Triggers.SysFVar)) { return EmitMethod(state, typeof(SpecialFunctions).GetMethod("Assignment_SysFVar"), args); } throw new Exception(); }
LocalVariableInfo EmitLogicalOperator(CompilerState state, Operator @operator, LocalVariableInfo lhs, LocalVariableInfo rhs) { if (state == null) throw new Exception(); if (lhs == null) throw new Exception(); if (rhs == null) throw new Exception(); LocalVariableInfo result = state.Generator.DeclareLocal(typeof(Int32)); PushAsBoolean(state, lhs); PushAsBoolean(state, rhs); switch (@operator) { case Operator.LogicalAnd: state.Generator.Emit(OpCodes.And); StoreLocalVariable(state, result); break; case Operator.LogicalOr: state.Generator.Emit(OpCodes.Or); StoreLocalVariable(state, result); break; case Operator.LogicalXor: state.Generator.Emit(OpCodes.Xor); StoreLocalVariable(state, result); break; default: throw new Exception(); } return result; }
internal override void EmitIl(ILGenerator il, CompilerState state) { MethodInfo info; if (PredefinedFunctions.TryGetMethodInfo(_identifier, out info)) { il.Emit(OpCodes.Call, info); } else { LocalBuilder func; if (!state.LoadedFunctions.TryGetValue(_identifier, out func)) { // The function hasn't been loaded by another token Label executeFunc = il.DefineLabel(); // Prevent the function from being loaded again func = il.DeclareLocal(typeof(Function)); state.LoadedFunctions.Add(_identifier, func); // User-defined function? EmitCheckFuncDefined(il, func, _identifier); // If the function is defined, move to the "executeFunc" label il.Emit(OpCodes.Brtrue_S, executeFunc); // Otherwise, throw an exception il.Emit(OpCodes.Ldstr, _identifier); il.Emit(OpCodes.Newobj, FunctionNotFoundInfo); il.Emit(OpCodes.Throw); il.MarkLabel(executeFunc); } // Create the parameter array for the function to be called il.Emit(OpCodes.Ldc_I4, _numArgs); // Push the number of arguments il.Emit(OpCodes.Newarr, typeof(double)); // New up an array // Holds the parameter array LocalBuilder paramArr = il.DeclareLocal(typeof(double[])); // Store the param array il.Emit(OpCodes.Stloc_S, paramArr); // Holds the argument before storing it into the array LocalBuilder argValue = il.DeclareLocal(typeof(double)); // Store each argument into the parameter array for (int i = 0; i < _numArgs; i++) { // Store the argument in a local il.Emit(OpCodes.Stloc_S, argValue); // Store the argument into the parameter array il.Emit(OpCodes.Ldloc_S, paramArr); // Push the param array il.Emit(OpCodes.Ldc_I4, i); // Push the index of the argument il.Emit(OpCodes.Ldloc_S, argValue); // Push the argument il.Emit(OpCodes.Stelem_R8); // Store the argument at the specified index } // Evaluate the function il.Emit(OpCodes.Ldloc_S, func); // Push the function instance il.Emit(OpCodes.Ldloc_S, paramArr); // Push the array il.Emit(OpCodes.Ldarg_1); // Push the Calculator instance il.Emit(OpCodes.Call, EvalFunctionInfo); // Evaluate the function } state.StackHeight -= _numArgs - 1; }
private void ChangeCompilerStateEvent(ICompiler sender, CompilerState State, string FileName) { this.state=State; }
LocalVariableInfo Emit(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); if (node.Token.Data is Evaluation.Tokenizing.NumberData) { return EmitNumber(state, node); } if (node.Token.Data is Evaluation.Tokenizing.OperatorData) { return EmitOperator(state, node); } if (node.Token.Data is Evaluation.Tokenizing.StateRedirectionData) { return EmitStateRedirection(state, node); } if (node.Token.Data is Evaluation.Tokenizing.CustomFunctionData) { return EmitFunction(state, node); } if (node.Token.Data is Evaluation.Tokenizing.RangeData) { return EmitRange(state, node); } throw new Exception(); }
internal override void EmitIl(ILGenerator il, CompilerState state) { switch (_identifier) { case "e": il.Emit(OpCodes.Ldc_R8, Math.E); break; case "pi": il.Emit(OpCodes.Ldc_R8, Math.PI); break; case Calculator.GraphingArgument: if (!state.OptimizeGraphingArgument) { // Handle the graphing argument just like any other argument goto default; } // Access the special graphing argument field from Calculator if (state.GraphingArgumentLocal == null) { state.GraphingArgumentLocal = il.DeclareLocal(typeof(double)); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldfld, GraphingArgumentValueInfo); il.Emit(OpCodes.Stloc, state.GraphingArgumentLocal); } il.Emit(OpCodes.Ldloc, state.GraphingArgumentLocal); break; default: if (!_retrieveFromParameter) { // Use Calculator.GetArgument() directly il.Emit(OpCodes.Ldarg_1); // Push the calculator il.Emit(OpCodes.Ldstr, _identifier); // Push the identifier il.Emit(OpCodes.Call, GetArgumentInfo); // Call GetArgument(), which pushes the value break; } // Add it to the compiled expression's arguments int argIndex; Argument arg = state.Arguments.Find(a => a.Identifier == _identifier); if (arg != null) { // This argument was already added argIndex = arg.Index; } else { // Create a new argument // The index refers to the array passed in to the compiled expression argIndex = state.Arguments.Count; state.Arguments.Add(new Argument(_identifier, argIndex)); } il.Emit(OpCodes.Ldarg_0); // Load the array from argument index 0 onto the stack il.Emit(OpCodes.Ldc_I4, argIndex); // Load the index of the argument in the array onto the stack // Push the value from the array onto the stack // The array instance and the index are subsequently popped from the stack il.Emit(OpCodes.Ldelem, typeof(double)); break; } state.StackHeight++; }
List<LocalVariableInfo> EmitRedirectionDescendants(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); List<LocalVariableInfo> output = new List<LocalVariableInfo>(); for (Int32 i = 0; i < node.Children.Count - 1; ++i) output.Add(Emit(state, node.Children[i])); foreach (Object arg in node.Arguments) { if (arg is String) { LocalVariableInfo local = state.Generator.DeclareLocal(typeof(String)); state.Generator.Emit(OpCodes.Ldstr, (String)arg); StoreLocalVariable(state, local); output.Add(local); } else if (arg.GetType().IsEnum == true) { LocalVariableInfo local = state.Generator.DeclareLocal(arg.GetType()); state.Generator.Emit(OpCodes.Ldc_I4, (Int32)arg); StoreLocalVariable(state, local); output.Add(local); } else { throw new Exception(); } } return output; }
void StoreLocalVariable(CompilerState state, LocalVariableInfo local) { if (state == null) throw new Exception(); if (local == null) throw new Exception(); switch (local.LocalIndex) { case 0: state.Generator.Emit(OpCodes.Stloc_0); break; case 1: state.Generator.Emit(OpCodes.Stloc_1); break; case 2: state.Generator.Emit(OpCodes.Stloc_2); break; case 3: state.Generator.Emit(OpCodes.Stloc_3); break; default: state.Generator.Emit(OpCodes.Stloc, local.LocalIndex); break; } }
LocalVariableInfo EmitNumber(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); Evaluation.Tokenizing.NumberData data = node.Token.Data as Evaluation.Tokenizing.NumberData; if (data == null) throw new Exception(); Number number = data.GetNumber(node.Token.ToString()); if (number.NumberType == NumberType.Int) { LocalVariableInfo local = state.Generator.DeclareLocal(typeof(Int32)); state.Generator.Emit(OpCodes.Ldc_I4, number.IntValue); StoreLocalVariable(state, local); return local; } if (number.NumberType == NumberType.Float) { LocalVariableInfo local = state.Generator.DeclareLocal(typeof(Single)); state.Generator.Emit(OpCodes.Ldc_R4, number.FloatValue); StoreLocalVariable(state, local); return local; } throw new Exception(); }
internal abstract void EmitIl(ILGenerator il, CompilerState state);
void ChangeCompilerState(CompilerState State, string FileName) { if (State == CompilerState.Ready && compilationSatarted) { compilationSatarted = false; if (CheckProcessMemory()) return; } compilerState = State; if (OnChangeCompilerState != null) OnChangeCompilerState(this, State, FileName); }
LocalVariableInfo EmitArithmeticOperator(CompilerState state, OpCode msilcode, LocalVariableInfo lhs, LocalVariableInfo rhs) { if (state == null) throw new Exception(); if (lhs == null) throw new Exception(); if (rhs == null) throw new Exception(); if (msilcode == OpCodes.Div) CheckIfZero(state, rhs); LocalVariableInfo result; if (lhs.LocalType == typeof(Int32) && rhs.LocalType == typeof(Int32)) { result = state.Generator.DeclareLocal(typeof(Int32)); LoadLocalVariable(state, lhs); LoadLocalVariable(state, rhs); } else { result = state.Generator.DeclareLocal(typeof(Single)); LoadLocalVariable(state, lhs); state.Generator.Emit(OpCodes.Conv_R4); LoadLocalVariable(state, rhs); state.Generator.Emit(OpCodes.Conv_R4); } state.Generator.Emit(msilcode); StoreLocalVariable(state, result); return result; }
internal override void EmitIl(ILGenerator il, CompilerState state) { Label mulBody = il.DefineLabel(); Label end = il.DefineLabel(); // The local holding the function instance LocalBuilder func; // Emit the single argument of the supposed function foreach (Token t in _argTokens) { t.EmitIl(il, state); } // Preserve the stack height so that any changes from the initialized tokens // below don't mess it up int oldHeight = state.StackHeight; if (!state.LoadedFunctions.TryGetValue(_identifier, out func)) { // Prevent the function from being loaded again func = il.DeclareLocal(typeof(Function)); state.LoadedFunctions.Add(_identifier, func); // Find out of the function is actually defined // If the function is defined, the `func` local will be loaded with the requested function, // and `true` will be pushed onto the stack; otherwise, `false` is pushed EmitCheckFuncDefined(il, func, _identifier); } else { // `false` and `null` are the same when evaluated by OpCodes.Brfalse, so if the function // doesn't exist (and the local has a `null` value in it), it will go to mulBody il.Emit(OpCodes.Ldloc, func); } // If the function wasn't defined, go to the multiplication code il.Emit(OpCodes.Brfalse, mulBody); // Emit the function code var funcToken = new FunctionToken(_identifier, 1); funcToken.EmitIl(il, state); // Skip past the multiplication body il.Emit(OpCodes.Br_S, end); // Emit the implicit multiplication code il.MarkLabel(mulBody); // Don't retrieve it from the parameter array, because if it is a function, then the argument // will be needlessly looked up and will not be used var argToken = new ArgumentToken(_identifier, false); argToken.EmitIl(il, state); var opToken = new OperatorToken(Operator.Multiply); opToken.EmitIl(il, state); il.MarkLabel(end); // Reset any changes the tokens initialized in this method made state.StackHeight = oldHeight; }
LocalVariableInfo EmitUnaryOperator(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); Evaluation.Tokenizing.OperatorData data = node.Token.Data as Evaluation.Tokenizing.OperatorData; if (data == null) throw new Exception(); if (node.Children.Count != 1) throw new Exception(); if (data.Operator == Operator.Minus) { LocalVariableInfo value = Emit(state, node.Children[0]); LocalVariableInfo result = state.Generator.DeclareLocal(value.LocalType); LoadLocalVariable(state, value); state.Generator.Emit(OpCodes.Neg); StoreLocalVariable(state, result); return result; } if (data.Operator == Operator.LogicalNot) { LocalVariableInfo value = Emit(state, node.Children[0]); LoadLocalVariable(state, value); LocalVariableInfo result = state.Generator.DeclareLocal(typeof(Int32)); Label l1 = state.Generator.DefineLabel(); Label l2 = state.Generator.DefineLabel(); state.Generator.Emit(OpCodes.Brtrue, l1); state.Generator.Emit(OpCodes.Ldc_I4_1); state.Generator.Emit(OpCodes.Br, l2); state.Generator.MarkLabel(l1); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.MarkLabel(l2); StoreLocalVariable(state, result); return result; } throw new Exception(); }
/// <summary> /// Return true if there is a dynamic or static predicate with name and arity. /// This returns false for built-in predicates. /// </summary> /// <param name="name"></param> /// <param name="arity"></param> /// <param name="declaringClass">used to resolve references to the default /// module Atom.a(""). If a declaringClass is needed to resolve the reference but it is /// null, return false</param> /// <returns></returns> public static bool isCurrentPredicate(Atom name, int arity, Type declaringClass) { CompilerState state = new CompilerState(); Variable FunctionName = new Variable(); foreach (bool l1 in functorCallFunctionName(state, name, arity, FunctionName)) { Atom functionNameAtom = ((Atom)FunctionName.getValue()); if (functionNameAtom == Atom.NIL) // name is for a dynamic predicate. return YP.isDynamicCurrentPredicate(name, arity); string methodName = functionNameAtom._name; if (methodName.StartsWith("YP.")) // current_predicate/1 should fail for built-ins. return false; if (methodName.Contains(".")) // We don't support calling inner classes, etc. return false; if (declaringClass == null) return false; foreach (MemberInfo member in declaringClass.GetMember(methodName)) { MethodInfo method = member as MethodInfo; if (method == null) continue; if ((method.Attributes | MethodAttributes.Static) == 0) // Not a static method. continue; if (method.GetParameters().Length == arity) return true; } } return false; }
List<LocalVariableInfo> EmitDescendants(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); List<LocalVariableInfo> output = new List<LocalVariableInfo>(); foreach (Node child in node.Children) output.Add(Emit(state, child)); foreach (Object arg in node.Arguments) { if (arg is String) { LocalVariableInfo local = state.Generator.DeclareLocal(typeof(String)); state.Generator.Emit(OpCodes.Ldstr, (String)arg); StoreLocalVariable(state, local); output.Add(local); } else if (arg.GetType().IsEnum == true) { LocalVariableInfo local = state.Generator.DeclareLocal(arg.GetType()); state.Generator.Emit(OpCodes.Ldc_I4, (Int32)arg); StoreLocalVariable(state, local); output.Add(local); } else if (arg is Combat.HitType[]) { LocalVariableInfo local = state.Generator.DeclareLocal(arg.GetType()); Combat.HitType[] hitypes = (Combat.HitType[])arg; state.Generator.Emit(OpCodes.Ldc_I4, hitypes.Length); state.Generator.Emit(OpCodes.Newarr, typeof(Combat.HitType)); StoreLocalVariable(state, local); for (Int32 i = 0; i != hitypes.Length; ++i) { LoadLocalVariable(state, local); state.Generator.Emit(OpCodes.Ldc_I4, i); state.Generator.Emit(OpCodes.Ldc_I4, (Int32)hitypes[i].Class); state.Generator.Emit(OpCodes.Ldc_I4, (Int32)hitypes[i].Power); state.Generator.Emit(OpCodes.Newobj, typeof(Combat.HitType).GetConstructor(new Type[] { typeof(AttackClass), typeof(AttackPower) })); state.Generator.Emit(OpCodes.Stelem, typeof(Combat.HitType)); } output.Add(local); } else { throw new Exception(); } } return output; }
LocalVariableInfo EmitMethod(CompilerState state, MethodInfo method, List<LocalVariableInfo> args) { if (state == null) throw new Exception(); if (method == null) throw new Exception(); if (args == null) throw new Exception(); ParameterInfo[] parameters = method.GetParameters(); for (Int32 i = 0; i != args.Count; ++i) { LoadLocalVariable(state, args[i]); if (parameters[i].ParameterType == typeof(Single) && args[i].LocalType != typeof(Single)) { state.Generator.Emit(OpCodes.Conv_R4); } if (parameters[i].ParameterType == typeof(Double) && args[i].LocalType != typeof(Double)) { state.Generator.Emit(OpCodes.Conv_R8); } } state.Generator.Emit(OpCodes.Call, method); Type returntype = method.ReturnType; if (returntype == typeof(Boolean)) { returntype = typeof(Int32); } else if (returntype == typeof(Double)) { state.Generator.Emit(OpCodes.Conv_R4); returntype = typeof(Single); } LocalVariableInfo result = state.Generator.DeclareLocal(returntype); StoreLocalVariable(state, result); LoadLocalVariable(state, state.ErrorVariable); state.Generator.Emit(OpCodes.Brtrue, state.ErrorLabel); return result; }
void CheckIfZero(CompilerState state, LocalVariableInfo local) { if (state == null) throw new Exception(); if (local == null) throw new Exception(); if (local.LocalType == typeof(Int32)) { LoadLocalVariable(state, local); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.Emit(OpCodes.Beq, state.ErrorLabel); } if (local.LocalType == typeof(Single)) { LoadLocalVariable(state, local); state.Generator.Emit(OpCodes.Ldc_R4, 0.0f); state.Generator.Emit(OpCodes.Beq, state.ErrorLabel); } }
LocalVariableInfo EmitRange(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); Evaluation.Tokenizing.RangeData data = node.Token.Data as Evaluation.Tokenizing.RangeData; if (data == null) throw new Exception(); if (node.Children.Count != 3) throw new Exception(); if (node.Arguments.Count != 3) throw new Exception(); List<LocalVariableInfo> args = EmitDescendants(state, node); Type[] argtypes = new Type[args.Count]; for (Int32 i = 0; i != args.Count; ++i) argtypes[i] = args[i].LocalType; MethodInfo method = typeof(SpecialFunctions).GetMethod("Range", argtypes); return EmitMethod(state, method, args); }
void PushAsBoolean(CompilerState state, LocalVariableInfo local) { if (state == null) throw new Exception(); if (local == null) throw new Exception(); Label l1 = state.Generator.DefineLabel(); Label l2 = state.Generator.DefineLabel(); LoadLocalVariable(state, local); if (local.LocalType == typeof(Int32)) { state.Generator.Emit(OpCodes.Brfalse, l1); } else if (local.LocalType == typeof(Single)) { state.Generator.Emit(OpCodes.Ldc_R4, 0); state.Generator.Emit(OpCodes.Beq, l1); } else { throw new Exception(); } state.Generator.Emit(OpCodes.Ldc_I4_1); state.Generator.Emit(OpCodes.Br, l2); state.Generator.MarkLabel(l1); state.Generator.Emit(OpCodes.Ldc_I4_0); state.Generator.MarkLabel(l2); }
LocalVariableInfo EmitStateRedirection(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); Evaluation.Tokenizing.StateRedirectionData data = node.Token.Data as Evaluation.Tokenizing.StateRedirectionData; if (data == null) throw new Exception(); if (node.Children.Count < 1) throw new Exception(); List<LocalVariableInfo> functionargs = EmitRedirectionDescendants(state, node); MethodInfo method = FindCorrectRedirectionMethod(data.Type, functionargs); ParameterInfo[] parameters = method.GetParameters(); LoadLocalVariable(state, state.FunctionState); state.Generator.Emit(OpCodes.Ldloca, state.ErrorVariable.LocalIndex); for (Int32 i = 0; i != functionargs.Count; ++i) { LocalVariableInfo arg = functionargs[i]; ParameterInfo parameter = parameters[i + 2]; LoadLocalVariable(state, arg); //if (parameter.ParameterType == typeof(Int32) && arg.LocalType == typeof(Single)) state.Generator.Emit(OpCodes.Conv_I4); //if (parameter.ParameterType == typeof(Single) && arg.LocalType == typeof(Int32)) state.Generator.Emit(OpCodes.Conv_R4); } state.Generator.Emit(OpCodes.Call, method); LocalVariableInfo oldstate = state.FunctionState; state.FunctionState = state.Generator.DeclareLocal(typeof(Object)); StoreLocalVariable(state, state.FunctionState); LoadLocalVariable(state, state.ErrorVariable); state.Generator.Emit(OpCodes.Brtrue, state.ErrorLabel); LocalVariableInfo returnvalue = Emit(state, node.Children[node.Children.Count - 1]); state.FunctionState = oldstate; return returnvalue; }
internal override void EmitIl(ILGenerator il, CompilerState state) { il.Emit(_opCode); state.StackHeight += _stackHeightModifier; }
LocalVariableInfo EmitFunction(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); Evaluation.Tokenizing.CustomFunctionData data = node.Token.Data as Evaluation.Tokenizing.CustomFunctionData; if (data == null) throw new Exception(); if (data.Type == typeof(Triggers.Const) || data.Type == typeof(Triggers.GetHitVar)) { return EmitSpecialFunction(state, data.Type, (String)node.Arguments[0]); } List<LocalVariableInfo> functionargs = EmitDescendants(state, node); MethodInfo method = FindCorrectMethod(data.Type, functionargs); ParameterInfo[] parameters = method.GetParameters(); LoadLocalVariable(state, state.FunctionState); state.Generator.Emit(OpCodes.Ldloca, state.ErrorVariable.LocalIndex); for (Int32 i = 0; i != functionargs.Count; ++i) { LocalVariableInfo arg = functionargs[i]; ParameterInfo parameter = parameters[i + 2]; LoadLocalVariable(state, arg); //if (parameter.ParameterType == typeof(Int32) && arg.LocalType == typeof(Single)) state.Generator.Emit(OpCodes.Conv_I4); //if (parameter.ParameterType == typeof(Single) && arg.LocalType == typeof(Int32)) state.Generator.Emit(OpCodes.Conv_R4); } state.Generator.Emit(OpCodes.Call, method); Type returntype = method.ReturnType; if (returntype == typeof(Boolean)) returntype = typeof(Int32); LocalVariableInfo result = state.Generator.DeclareLocal(returntype); StoreLocalVariable(state, result); LoadLocalVariable(state, state.ErrorVariable); state.Generator.Emit(OpCodes.Brtrue, state.ErrorLabel); return result; }
LocalVariableInfo EmitSpecialFunction(CompilerState state, Type type, String constant) { if (state == null) throw new Exception(); if (type == null) throw new Exception(); if (constant == null) throw new Exception(); Dictionary<String, MethodInfo> methodmap; if (type == typeof(Triggers.Const)) methodmap = m_constfunctionmethods; else if (type == typeof(Triggers.GetHitVar)) methodmap = m_gethitvarmethods; else throw new Exception(); MethodInfo method; if (methodmap.TryGetValue(constant, out method) == false) throw new Exception(); LoadLocalVariable(state, state.FunctionState); state.Generator.Emit(OpCodes.Ldloca, state.ErrorVariable.LocalIndex); state.Generator.Emit(OpCodes.Call, method); Type returntype = method.ReturnType; if (returntype == typeof(Boolean)) returntype = typeof(Int32); LocalVariableInfo result = state.Generator.DeclareLocal(returntype); StoreLocalVariable(state, result); LoadLocalVariable(state, state.ErrorVariable); state.Generator.Emit(OpCodes.Brtrue, state.ErrorLabel); return result; }
LocalVariableInfo EmitOperator(CompilerState state, Node node) { if (state == null) throw new Exception(); if (node == null) throw new Exception(); Evaluation.Tokenizing.OperatorData data = node.Token.Data as Evaluation.Tokenizing.OperatorData; if (data == null) throw new Exception(); if (node.Children.Count == 1) return EmitUnaryOperator(state, node); if (node.Children.Count != 2) throw new Exception(); if (data.Operator == Operator.Assignment) return EmitAssignmentOperator(state, node); LocalVariableInfo lhs = Emit(state, node.Children[0]); LocalVariableInfo rhs = Emit(state, node.Children[1]); switch (data.Operator) { case Operator.Plus: return EmitArithmeticOperator(state, OpCodes.Add, lhs, rhs); case Operator.Minus: return EmitArithmeticOperator(state, OpCodes.Sub, lhs, rhs); case Operator.Divide: return EmitArithmeticOperator(state, OpCodes.Div, lhs, rhs); case Operator.Multiply: return EmitArithmeticOperator(state, OpCodes.Mul, lhs, rhs); case Operator.Modulus: return EmitArithmeticOperator(state, OpCodes.Rem, lhs, rhs); case Operator.Equals: case Operator.NotEquals: case Operator.Greater: case Operator.GreaterEquals: case Operator.Lesser: case Operator.LesserEquals: return EmitComparsionOperator(state, data.Operator, lhs, rhs); case Operator.LogicalAnd: case Operator.LogicalOr: case Operator.LogicalXor: return EmitLogicalOperator(state, data.Operator, lhs, rhs); case Operator.Exponent: return EmitMethod(state, typeof(Math).GetMethod("Pow"), new List<LocalVariableInfo>() { lhs, rhs }); default: throw new Exception(); } }
/// <summary> /// If the functor with name and args can be called directly as determined by /// functorCallFunctionName, then call it and return its iterator. If the predicate is /// dynamic and undefined, or if static and the method cannot be found, return /// the result of YP.unknownPredicate. /// This returns null if the functor has a special form than needs to be compiled /// (including ,/2 and ;/2). /// </summary> /// <param name="name"></param> /// <param name="args"></param> /// <param name="declaringClass">used to resolve references to the default /// module Atom.a(""). If a declaringClass is needed to resolve the reference but it is /// null, this throws a PrologException for existence_error</param> /// <returns></returns> public static IEnumerable<bool> getSimpleIterator(Atom name, object[] args, Type declaringClass) { CompilerState state = new CompilerState(); Variable FunctionName = new Variable(); foreach (bool l1 in functorCallFunctionName(state, name, args.Length, FunctionName)) { Atom functionNameAtom = ((Atom)FunctionName.getValue()); if (functionNameAtom == Atom.NIL) // name is for a dynamic predicate. return YP.matchDynamic(name, args); string methodName = functionNameAtom._name; // Set the default for the method to call. Type methodClass = declaringClass; bool checkMode = false; if (methodName.StartsWith("YP.")) { // Assume we only check mode in calls to standard Prolog predicates in YP. checkMode = true; // Use the method in class YP. methodName = methodName.Substring(3); methodClass = typeof(YP); } if (methodName.Contains(".")) // We don't support calling inner classes, etc. return null; if (methodClass == null) return YP.unknownPredicate (name, args.Length, "Cannot find predicate function for: " + name + "/" + args.Length + " because declaringClass is null. Set declaringClass to the class containing " + methodName); try { if (checkMode) { assertYPPred(state); object functor = Functor.make(name, args); if (CompilerState.isDetNoneOut(state, functor)) { methodClass.InvokeMember (methodName, BindingFlags.InvokeMethod, null, null, args); return YP.succeed(); } if (CompilerState.isSemidetNoneOut(state, functor)) { if ((bool)methodClass.InvokeMember (methodName, BindingFlags.InvokeMethod, null, null, args)) return YP.succeed(); else return YP.fail(); } } return (IEnumerable<bool>)methodClass.InvokeMember (methodName, BindingFlags.InvokeMethod, null, null, args); } catch (TargetInvocationException exception) { throw exception.InnerException; } catch (MissingMethodException) { return YP.unknownPredicate (name, args.Length, "Cannot find predicate function " + methodName + " for " + name + "/" + args.Length + " in " + methodClass.FullName); } } return null; }
public string Compile() { errorsList.Clear(); warnings.Clear(); //sendObject(ConsoleCompilerConstants.InternalDebug, internalDebug); //sendObject(ConsoleCompilerConstants.CompilerOptions, compilerOptions); waitCompilerReloading(); sendCompilerOptions(); compilerState = CompilerState.CompilationStarting; compilationSatarted = true; sendCommand(ConsoleCompilerConstants.CommandCompile); while (compilerState != CompilerState.Ready) Thread.Sleep(5); if (errorsList.Count > 0) return null; return compilerOptions.OutputFileName; }