public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes) { // Set default values. if (!HasConnectedInput(0)) { inputAstNodes[0] = new IntNode(0); } if (!HasConnectedInput(1)) { inputAstNodes[1] = new IntNode(9); } if (!HasConnectedInput(2)) { inputAstNodes[2] = new IntNode(1); } return new[] { AstFactory.BuildAssignment( GetAstIdentifierForOutputIndex(0), new RangeExprNode { From = inputAstNodes[0], To = inputAstNodes[1], Step = inputAstNodes[2], StepOperator = ProtoCore.DSASM.RangeStepOperator.StepSize }) }; }
public RangeExprNode() { IntNode defaultStep = new IntNode(); defaultStep.value = "1"; StepNode = defaultStep; }
public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes) { AssociativeNode rhs = null; if (IsPartiallyApplied) { var connectedInputs = new List<AssociativeNode>(); var functionNode = new IdentifierNode(functionName); var paramNumNode = new IntNode(1); var positionNode = AstFactory.BuildExprList(connectedInputs); var arguments = AstFactory.BuildExprList(inputAstNodes); var inputParams = new List<AssociativeNode> { functionNode, paramNumNode, positionNode, arguments, AstFactory.BuildBooleanNode(true) }; rhs = AstFactory.BuildFunctionCall("_SingleFunctionObject", inputParams); } else { rhs = AstFactory.BuildFunctionCall(functionName, inputAstNodes); } return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), rhs) }; }
public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes) { if (HasUnconnectedInput()) { var connectedInput = Enumerable.Range(0, InPortData.Count) .Where(HasConnectedInput) .Select(x => new IntNode(x) as AssociativeNode) .ToList(); var paramNumNode = new IntNode(InPortData.Count); var positionNode = AstFactory.BuildExprList(connectedInput); var arguments = AstFactory.BuildExprList(inputAstNodes); var functionNode = new IdentifierListNode { LeftNode = new IdentifierNode("DSCore.List"), RightNode = new IdentifierNode("__Create") }; var inputParams = new List<AssociativeNode> { functionNode, paramNumNode, positionNode, arguments, AstFactory.BuildBooleanNode(false) }; return new[] { AstFactory.BuildAssignment( GetAstIdentifierForOutputIndex(0), AstFactory.BuildFunctionCall("_SingleFunctionObject", inputParams)) }; } else { return new[] { AstFactory.BuildAssignment( GetAstIdentifierForOutputIndex(0), AstFactory.BuildExprList(inputAstNodes)) }; } }
public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes) { var lhs = GetAstIdentifierForOutputIndex(0); AssociativeNode rhs; if (IsPartiallyApplied) { var connectedInputs = Enumerable.Range(0, InPorts.Count) .Where(index=>InPorts[index].IsConnected) .Select(x => new IntNode(x) as AssociativeNode) .ToList(); var functionNode = new IdentifierNode(Constants.kInlineConditionalMethodName); var paramNumNode = new IntNode(3); var positionNode = AstFactory.BuildExprList(connectedInputs); var arguments = AstFactory.BuildExprList(inputAstNodes); var inputParams = new List<AssociativeNode> { functionNode, paramNumNode, positionNode, arguments, AstFactory.BuildBooleanNode(true) }; rhs = AstFactory.BuildFunctionCall("__CreateFunctionObject", inputParams); } else { rhs = new InlineConditionalNode { ConditionExpression = inputAstNodes[0], TrueExpression = inputAstNodes[1], FalseExpression = inputAstNodes[2] }; } return new[] { AstFactory.BuildAssignment(lhs, rhs) }; }
void Associative_Number(out ProtoCore.AST.AssociativeAST.AssociativeNode node) { node = null; int sign = 1; int line = ProtoCore.DSASM.Constants.kInvalidIndex; int col = ProtoCore.DSASM.Constants.kInvalidIndex; if (la.kind == 15) { Get(); sign = -1; line = t.line; col = t.col; } if (la.kind == 2) { Get(); Int64 value; if (Int64.TryParse(t.val, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture, out value)) { node = new ProtoCore.AST.AssociativeAST.IntNode(value * sign); } else { node = new ProtoCore.AST.AssociativeAST.NullNode(); } if (ProtoCore.DSASM.Constants.kInvalidIndex == line && ProtoCore.DSASM.Constants.kInvalidIndex == col) { NodeUtils.SetNodeLocation(node, t); } else { node.line = line; node.col = col; node.endLine = t.line; node.endCol = t.col; } } else if (la.kind == 3) { Get(); double value; if (Double.TryParse(t.val, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out value)) { node = new ProtoCore.AST.AssociativeAST.DoubleNode(value * sign); } else { node = new ProtoCore.AST.AssociativeAST.NullNode(); } if (ProtoCore.DSASM.Constants.kInvalidIndex == line && ProtoCore.DSASM.Constants.kInvalidIndex == col) { NodeUtils.SetNodeLocation(node, t); } else { node.line = line; node.col = col; } } else SynErr(98); }
/// <summary> /// TODO: Deprecate /// Emit IntNode or DoubleNode /// </summary> /// <param name="node"></param> /// <param name="outnode"></param> private void EmitLiteralNode(LiteralNode node, out AssociativeNode outnode) { Validity.Assert(node != null); Validity.Assert(node.children.Count == 0); // Create temp identifier and assign it to the literal (IntNode or DoubleNode) to create a BinaryExpressionNode // Return the temp IdentifierNode //BinaryExpressionNode expressionNode = new BinaryExpressionNode(); AssociativeNode rightNode = null; Int64 number; double real; bool flag; string val = node.ToScript(); // If LiternalNode is double if(Double.TryParse(val, NumberStyles.Number, CultureInfo.InvariantCulture, out real)) { rightNode = new DoubleNode(real); } // If LiteralNode type is Int else if (Int64.TryParse(val, NumberStyles.Number, CultureInfo.InvariantCulture, out number)) { rightNode = new IntNode(number); } // If LiteralNode is bool else if (Boolean.TryParse(val, out flag)) { rightNode = new BooleanNode(flag); } /*IdentifierNode ident = CreateTempIdentifierNode(node); expressionNode.RightNode = rightNode; expressionNode.LeftNode = ident; expressionNode.Optr = ProtoCore.DSASM.Operator.assign;*/ //(AstRootNode as CodeBlockNode).Body.Add(expressionNode); //outnode = expressionNode; outnode = CreateBinaryExpNode(node, rightNode); }
void Associative_Number(out ProtoCore.AST.AssociativeAST.AssociativeNode node) { node = null; String localvalue = String.Empty; int line = ProtoCore.DSASM.Constants.kInvalidIndex; int col = ProtoCore.DSASM.Constants.kInvalidIndex; if (la.kind == 12) { Get(); localvalue = "-"; line = t.line; col = t.col; } if (la.kind == 2) { Get(); node = new ProtoCore.AST.AssociativeAST.IntNode() { value = localvalue + t.val }; if ( ProtoCore.DSASM.Constants.kInvalidIndex == line && ProtoCore.DSASM.Constants.kInvalidIndex == col) { NodeUtils.SetNodeLocation(node, t); } else { node.line = line; node.col = col; } } else if (la.kind == 3) { Get(); node = new ProtoCore.AST.AssociativeAST.DoubleNode() { value = localvalue + t.val }; if ( ProtoCore.DSASM.Constants.kInvalidIndex == line && ProtoCore.DSASM.Constants.kInvalidIndex == col) { NodeUtils.SetNodeLocation(node, t); } else { node.line = line; node.col = col; } } else SynErr(101); }
public void DFSTraverse(ref AST.AssociativeAST.AssociativeNode node) { if (node is AST.AssociativeAST.IdentifierNode) { EmitIdentifierNode(ref node); } else if (node is ProtoCore.AST.AssociativeAST.IdentifierListNode) { AST.AssociativeAST.IdentifierListNode identList = node as ProtoCore.AST.AssociativeAST.IdentifierListNode; EmitIdentifierListNode(ref identList); } else if (node is ProtoCore.AST.AssociativeAST.IntNode) { AST.AssociativeAST.IntNode intNode = node as ProtoCore.AST.AssociativeAST.IntNode; EmitIntNode(ref intNode); } else if (node is ProtoCore.AST.AssociativeAST.DoubleNode) { AST.AssociativeAST.DoubleNode doubleNode = node as ProtoCore.AST.AssociativeAST.DoubleNode; EmitDoubleNode(ref doubleNode); } else if (node is ProtoCore.AST.AssociativeAST.FunctionCallNode) { AST.AssociativeAST.FunctionCallNode funcCallNode = node as ProtoCore.AST.AssociativeAST.FunctionCallNode; EmitFunctionCallNode(ref funcCallNode); } else if (node is ProtoCore.AST.AssociativeAST.FunctionDotCallNode) { AST.AssociativeAST.FunctionDotCallNode funcDotCall = node as ProtoCore.AST.AssociativeAST.FunctionDotCallNode; EmitFunctionDotCallNode(ref funcDotCall); } else if (node is ProtoCore.AST.AssociativeAST.BinaryExpressionNode) { ProtoCore.AST.AssociativeAST.BinaryExpressionNode binaryExpr = node as ProtoCore.AST.AssociativeAST.BinaryExpressionNode; if (binaryExpr.Optr != DSASM.Operator.assign) { ; } //EmitCode("("); EmitBinaryNode(ref binaryExpr); if (binaryExpr.Optr == DSASM.Operator.assign) { //EmitCode(ProtoCore.DSASM.Constants.termline); } if (binaryExpr.Optr != DSASM.Operator.assign) { ; } //EmitCode(")"); } else if (node is ProtoCore.AST.AssociativeAST.FunctionDefinitionNode) { AST.AssociativeAST.FunctionDefinitionNode funcDefNode = node as ProtoCore.AST.AssociativeAST.FunctionDefinitionNode; EmitFunctionDefNode(ref funcDefNode); } else if (node is ProtoCore.AST.AssociativeAST.ClassDeclNode) { AST.AssociativeAST.ClassDeclNode classDeclNode = node as ProtoCore.AST.AssociativeAST.ClassDeclNode; EmitClassDeclNode(ref classDeclNode); } else if (node is ProtoCore.AST.AssociativeAST.NullNode) { AST.AssociativeAST.NullNode nullNode = node as ProtoCore.AST.AssociativeAST.NullNode; EmitNullNode(ref nullNode); } else if (node is ProtoCore.AST.AssociativeAST.ArrayIndexerNode) { AST.AssociativeAST.ArrayIndexerNode arrIdxNode = node as ProtoCore.AST.AssociativeAST.ArrayIndexerNode; EmitArrayIndexerNode(ref arrIdxNode); } else if (node is ProtoCore.AST.AssociativeAST.ExprListNode) { AST.AssociativeAST.ExprListNode exprListNode = node as ProtoCore.AST.AssociativeAST.ExprListNode; EmitExprListNode(ref exprListNode); } }
private void TraverseDotCallArguments(FunctionCallNode funcCall, FunctionDotCallNode dotCall, ProcedureNode procCallNode, List<ProtoCore.Type> arglist, string procName, int classIndex, string className, bool isStaticCall, bool isConstructor, GraphNode graphNode, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass, BinaryExpressionNode bnode) { // Update graph dependencies if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier && graphNode != null) { if (isStaticCall) { Validity.Assert(classIndex != Constants.kInvalidIndex); Validity.Assert(!string.IsNullOrEmpty(className)); SymbolNode classSymbol = new SymbolNode(); classSymbol.name = className; classSymbol.classScope = classIndex; PushSymbolAsDependent(classSymbol, graphNode); } } int funtionArgCount = 0; for (int n = 0; n < funcCall.FormalArguments.Count; ++n) { if (isStaticCall || isConstructor) { if (n != Constants.kDotArgIndexArrayArgs) { continue; } } AssociativeNode paramNode = funcCall.FormalArguments[n]; ProtoCore.Type paramType = TypeSystem.BuildPrimitiveTypeObject(PrimitiveType.kTypeVar, 0); emitReplicationGuide = false; // If it's a binary node then continue type check, otherwise // disable type check and just take the type of paramNode itself enforceTypeCheck = !(paramNode is BinaryExpressionNode); if (ProtoCore.DSASM.Constants.kDotArgIndexPtr == n) { // Traversing the first arg (the LHS pointer/Static instanct/Constructor // Replication guides only allowed on method, e.g., // // x = p<1>.f({1,2}<2>); // // But not on getter, e.g., // // c = a<1>.x<2>; if (!CoreUtils.IsGetterSetter(procName) && !isConstructor) { emitReplicationGuide = true; } DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode); } else if (ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs == n) { // Traversing the actual arguments passed into the function // (not the dot function) int defaultArgNumber = 0; // If its null this is the second call in a chained dot if (null != procCallNode) { defaultArgNumber = procCallNode.ArgumentInfos.Count - dotCall.FunctionCall.FormalArguments.Count; } // Enable graphnode dependencies if its a setter method bool allowDependentState = null != graphNode ? graphNode.allowDependents : false; if (CoreUtils.IsSetter(procName)) { // If the arguments are not temporaries ExprListNode exprList = paramNode as ExprListNode; Validity.Assert(1 == exprList.Exprs.Count); string varname = string.Empty; if (exprList.Exprs[0] is IdentifierNode) { varname = (exprList.Exprs[0] as IdentifierNode).Name; if (!CoreUtils.IsAutoGeneratedVar(varname)) { graphNode.allowDependents = true; } else if (CoreUtils.IsSSATemp(varname) && core.Options.GenerateSSA) { graphNode.allowDependents = true; } } else { graphNode.allowDependents = true; } } emitReplicationGuide = true; if (defaultArgNumber > 0) { ExprListNode exprList = paramNode as ExprListNode; if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { for (int i = 0; i < defaultArgNumber; i++) { exprList.Exprs.Add(new DefaultArgNode()); } } if (!isStaticCall && !isConstructor) { DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); funtionArgCount = exprList.Exprs.Count; } else { foreach (AssociativeNode exprListNode in exprList.Exprs) { bool repGuideState = emitReplicationGuide; if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { emitReplicationGuide = false; } DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode); emitReplicationGuide = repGuideState; arglist.Add(paramType); } } } else { ExprListNode exprList = paramNode as ExprListNode; // Comment Jun: This is a getter/setter or a an auto-generated thisarg function... // ...add the dynamic sv that will be resolved as a pointer at runtime if (!isStaticCall && !isConstructor) { // TODO Jun: pls get rid of subPass checking outside the core travesal if (ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone == subPass) { exprList.Exprs.Insert(0, new DynamicNode()); } } if (exprList.Exprs.Count > 0) { foreach (AssociativeNode exprListNode in exprList.Exprs) { bool repGuideState = emitReplicationGuide; if (subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { emitReplicationGuide = false; } DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode); emitReplicationGuide = repGuideState; arglist.Add(paramType); } if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier && !isStaticCall && !isConstructor) { EmitInstrConsole(ProtoCore.DSASM.kw.alloca, exprList.Exprs.Count.ToString()); EmitPopArray(exprList.Exprs.Count); if (exprList.ArrayDimensions != null) { int dimensions = DfsEmitArrayIndexHeap(exprList.ArrayDimensions, graphNode); EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]"); EmitPushArrayIndex(dimensions); } } } else { if (!isStaticCall && !isConstructor) { if (exprList != null) { bool emitReplicationGuideState = emitReplicationGuide; emitReplicationGuide = false; DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); emitReplicationGuide = emitReplicationGuideState; } else { DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); } } } funtionArgCount = exprList.Exprs.Count; } emitReplicationGuide = false; // Restore the state only if it is a setter method if (ProtoCore.Utils.CoreUtils.IsSetter(procName)) { graphNode.allowDependents = allowDependentState; } } else if (ProtoCore.DSASM.Constants.kDotArgIndexArgCount == n) { IntNode argNumNode = new IntNode(funtionArgCount); DfsTraverse(argNumNode, ref paramType, false, graphNode, subPass); } else { DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); } emitReplicationGuide = false; enforceTypeCheck = true; if (!isStaticCall || !isConstructor) { arglist.Add(paramType); } } }
private void EmitRangeExprNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { RangeExprNode range = node as RangeExprNode; // Do some static checking... if ((range.FromNode is IntNode || range.FromNode is DoubleNode) && (range.ToNode is IntNode || range.ToNode is DoubleNode) && (range.StepNode == null || (range.StepNode != null && (range.StepNode is IntNode || range.StepNode is DoubleNode)))) { decimal current = (range.FromNode is IntNode) ? Int64.Parse((range.FromNode as IntNode).value) : Decimal.Parse((range.FromNode as DoubleNode).value); decimal end = (range.ToNode is IntNode) ? Int64.Parse((range.ToNode as IntNode).value) : Decimal.Parse((range.ToNode as DoubleNode).value); ProtoCore.DSASM.RangeStepOperator stepoperator = range.stepoperator; decimal step = 1; if (range.StepNode != null) { step = (range.StepNode is IntNode) ? Int64.Parse((range.StepNode as IntNode).value) : Decimal.Parse((range.StepNode as DoubleNode).value); } if (stepoperator == ProtoCore.DSASM.RangeStepOperator.stepsize) { if (range.StepNode == null && end < current) { step = -1; } if (step == 0) { buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithStepSizeZero, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col); EmitNullNode(new NullNode(), ref inferedType); return; } if ((end > current && step < 0) || (end < current && step > 0)) { buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithInvalidStepSize, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col); EmitNullNode(new NullNode(), ref inferedType); return; } } else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.num) { if (range.StepNode != null && !(range.StepNode is IntNode)) { buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithNonIntegerStepNumber, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col); EmitNullNode(new NullNode(), ref inferedType); return; } if (step <= 0) { buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithNegativeStepNumber, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col); EmitNullNode(new NullNode(), ref inferedType); return; } } else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.approxsize) { if (step == 0) { buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kInvalidRangeExpression, ProtoCore.BuildData.WarningMessage.kRangeExpressionWithStepSizeZero, compileStateTracker.CurrentDSFileName, range.StepNode.line, range.StepNode.col); EmitNullNode(new NullNode(), ref inferedType); return; } } } // Replace with build-in RangeExpression() function. - Yu Ke bool emitReplicationgGuideState = emitReplicationGuide; emitReplicationGuide = false; BooleanNode hasStep = new BooleanNode { value = range.StepNode == null ? "false" : "true" }; IntNode op = new IntNode(); switch (range.stepoperator) { case ProtoCore.DSASM.RangeStepOperator.stepsize: op.value = "0"; break; case ProtoCore.DSASM.RangeStepOperator.num: op.value = "1"; break; case ProtoCore.DSASM.RangeStepOperator.approxsize: op.value = "2"; break; default: op.value = "-1"; break; } var rangeExprFunc = nodeBuilder.BuildFunctionCall(Constants.kFunctionRangeExpression, new List<AssociativeNode> { range.FromNode, range.ToNode, range.StepNode == null ? new NullNode() : range.StepNode, op, hasStep }); EmitFunctionCallNode(rangeExprFunc, ref inferedType, false, graphNode, subPass); emitReplicationGuide = emitReplicationgGuideState; if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { if (range.ArrayDimensions != null) { int dimensions = DfsEmitArrayIndexHeap(range.ArrayDimensions, graphNode); EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]"); EmitPushArrayIndex(dimensions); } if (compileStateTracker.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { int replicationGuideNumber = EmitReplicationGuides(range.ReplicationGuides); EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, replicationGuideNumber + "[guide]"); EmitPushReplicationGuide(replicationGuideNumber); } } }
private void EmitRangeExprNode(AssociativeNode node, ref ProtoCore.Type inferedType, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone) { // (Ayush) Using Decimal type instead of Double for the sake of precision. For eg. doing 0.3d - 0.1d gives a result a little less than 0.2. These inaccuracies propogate // through a range expression and quickly cause wrong values to be returned. RangeExprNode range = node as RangeExprNode; if ((range.FromNode is NullNode || range.FromNode is BooleanNode) || (range.ToNode is NullNode || range.ToNode is BooleanNode) || (range.StepNode is NullNode || range.StepNode is BooleanNode)) { throw new ProtoCore.Exceptions.CompileErrorsOccured("Invalid range expression"); } else if ((range.FromNode is IntNode || range.FromNode is DoubleNode) && (range.ToNode is IntNode || range.ToNode is DoubleNode) && (range.StepNode is IntNode || range.StepNode is DoubleNode)) { ProtoCore.Type type = new ProtoCore.Type(); type.UID = (int)PrimitiveType.kTypeVoid; type.IsIndexable = true; type.Name = "double"; type.UID = (int)ProtoCore.PrimitiveType.kTypeDouble; type.rank = 1; int totalSteps = 0; bool terminate = false; decimal current = (range.FromNode is IntNode) ? Int64.Parse((range.FromNode as IntNode).value) : Decimal.Parse((range.FromNode as DoubleNode).value); decimal end = (range.ToNode is IntNode) ? Int64.Parse((range.ToNode as IntNode).value) : Decimal.Parse((range.ToNode as DoubleNode).value); ProtoCore.DSASM.RangeStepOperator stepoperator = range.stepoperator; decimal step = (range.StepNode is IntNode) ? Int64.Parse((range.StepNode as IntNode).value) : Decimal.Parse((range.StepNode as DoubleNode).value); decimal stepsize = 1.0M; if (stepoperator == ProtoCore.DSASM.RangeStepOperator.stepsize) { if (step == 0) { return; } if ((end > current && step < 0) || (end < current && step > 0)) { return; } stepsize = step; } else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.num) { if (!(range.StepNode is IntNode)) { return; } if (step <= 0) { return; } if ((step - 1) == 0) stepsize = 0; else stepsize = (end - current) / (step - 1); } else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.approxsize) { if (step == 0) { return; } RangeExprNode rnode = range; IntNode newStep = new IntNode(); rnode.StepNode = newStep; rnode.stepoperator = ProtoCore.DSASM.RangeStepOperator.num; decimal dist = end - current; if (dist == 0) { newStep.value = "1"; } else { decimal ceilStepSize = Math.Ceiling((dist) / step); decimal floorStepSize = Math.Floor((dist) / step); decimal numOfSteps; if ((ceilStepSize == 0) || (floorStepSize == 0)) numOfSteps = 2; else numOfSteps = (Math.Abs(dist / ceilStepSize - step) < Math.Abs(dist / floorStepSize - step)) ? ceilStepSize + 1 : floorStepSize + 1; newStep.value = numOfSteps.ToString(); } EmitRangeExprNode(rnode, ref inferedType); return; } bool isIntArray = (range.FromNode is IntNode) && (range.ToNode is IntNode) && (range.StepNode is IntNode) && (Math.Equals(stepsize, Math.Truncate(stepsize))); if (isIntArray) { type.Name = "int"; type.UID = (int)ProtoCore.PrimitiveType.kTypeInt; } if (stepsize == 0) { for (int i = 0; i < step; ++i) { if (isIntArray) EmitIntNode(new IntNode { value = current.ToString() }, ref type); else EmitDoubleNode(new DoubleNode { value = current.ToString() }, ref type); ++totalSteps; } } else { while (true) { if (stepoperator == ProtoCore.DSASM.RangeStepOperator.stepsize) terminate = (step < 0) ? ((current < end) ? true : false) : ((current > end) ? true : false); else if (stepoperator == ProtoCore.DSASM.RangeStepOperator.num) terminate = (totalSteps >= step) ? true : false; if (terminate) break; if (isIntArray) EmitIntNode(new IntNode { value = current.ToString() }, ref type); else EmitDoubleNode(new DoubleNode { value = current.ToString() }, ref type); current += stepsize; ++totalSteps; } } inferedType = type; } else { // traverse the from node DfsTraverse(range.FromNode, ref inferedType); // traverse the To node DfsTraverse(range.ToNode, ref inferedType); // traverse the step node DfsTraverse(range.StepNode, ref inferedType, false, null, subPass); inferedType.IsIndexable = true; inferedType.rank++; } }
void Associative_Number(out ProtoCore.AST.AssociativeAST.AssociativeNode node) { node = null; int sign = 1; int line = ProtoCore.DSASM.Constants.kInvalidIndex; int col = ProtoCore.DSASM.Constants.kInvalidIndex; if (la.kind == 13) { Get(); sign = -1; line = t.line; col = t.col; } if (la.kind == 2) { Get(); Int64 value; if (Int64.TryParse(t.val, out value)) { node = new ProtoCore.AST.AssociativeAST.IntNode(value * sign); } else { node = new ProtoCore.AST.AssociativeAST.NullNode(); } if (ProtoCore.DSASM.Constants.kInvalidIndex == line && ProtoCore.DSASM.Constants.kInvalidIndex == col) { NodeUtils.SetNodeLocation(node, t); } else { node.line = line; node.col = col; } } else if (la.kind == 3) { Get(); double value; if (Double.TryParse(t.val, out value)) { node = new ProtoCore.AST.AssociativeAST.DoubleNode(value * sign); } else { node = new ProtoCore.AST.AssociativeAST.NullNode(); } if (ProtoCore.DSASM.Constants.kInvalidIndex == line && ProtoCore.DSASM.Constants.kInvalidIndex == col) { NodeUtils.SetNodeLocation(node, t); } else { node.line = line; node.col = col; } } else SynErr(104); }
public static FunctionDotCallNode GenerateCallDotNode(AssociativeNode lhs, FunctionCallNode rhsCall, Core core = null) { // The function name to call string rhsName = rhsCall.Function.Name; int argNum = rhsCall.FormalArguments.Count; ExprListNode argList = new ExprListNode(); foreach (AssociativeNode arg in rhsCall.FormalArguments) { // The function arguments argList.Exprs.Add(arg); } var arguments = new List<AssociativeNode>(); int rhsIdx = DSASM.Constants.kInvalidIndex; string lhsName = string.Empty; if (lhs is IdentifierNode) { lhsName = (lhs as IdentifierNode).Name; if (lhsName == DSDefinitions.Keyword.This) { lhs = new ThisPointerNode(); } } if (core != null) { DynamicFunction func; if (core.DynamicFunctionTable.TryGetFunction(rhsName, 0, Constants.kInvalidIndex, out func)) { rhsIdx = func.Index; } else { func = core.DynamicFunctionTable.AddNewFunction(rhsName, 0, Constants.kInvalidIndex); rhsIdx = func.Index; } } // The first param to the dot arg (the pointer or the class name) arguments.Add(lhs); // The second param which is the dynamic table index of the function to call arguments.Add(new IntNode(rhsIdx)); // The array dimensions ExprListNode arrayDimExperList = new ExprListNode(); int dimCount = 0; if (rhsCall.Function is IdentifierNode) { // Number of dimensions IdentifierNode fIdent = rhsCall.Function as IdentifierNode; if (fIdent.ArrayDimensions != null) { arrayDimExperList = CoreUtils.BuildArrayExprList(fIdent.ArrayDimensions); dimCount = arrayDimExperList.Exprs.Count; } else if (rhsCall.ArrayDimensions != null) { arrayDimExperList = CoreUtils.BuildArrayExprList(rhsCall.ArrayDimensions); dimCount = arrayDimExperList.Exprs.Count; } else { arrayDimExperList = new ExprListNode(); } } arguments.Add(arrayDimExperList); // Number of dimensions var dimNode = new IntNode(dimCount); arguments.Add(dimNode); if (argNum >= 0) { arguments.Add(argList); arguments.Add(new IntNode(argNum)); } var funDotCallNode = new FunctionDotCallNode(rhsCall, arguments); // funDotCallNode.FunctionCall.Function = rhsCall.Function; NodeUtils.SetNodeEndLocation(funDotCallNode, rhsCall); return funDotCallNode; }
public void GetStatementVariables01() { // Create a statement of "Value = 1234". var leftNode = new IdentifierNode("Value"); var rightNode = new IntNode(1234); var binExprNode = new BinaryExpressionNode( leftNode, rightNode, Operator.assign); var statements = new List<Statement> { Statement.CreateInstance(binExprNode) }; var vars = CodeBlockUtils.GetStatementVariables(statements, true); Assert.IsNotNull(vars); Assert.AreEqual(1, vars.Count()); var variables = vars.ElementAt(0); Assert.IsNotNull(variables); Assert.AreEqual(1, variables.Count()); Assert.AreEqual("Value", variables.ElementAt(0)); }
private AssociativeNode CreateFunctionObject( AssociativeNode functionNode, List<AssociativeNode> inputs) { var paramNumNode = new IntNode(this.GetInputIndex()); var positionNode = AstFactory.BuildExprList(GetConnectedInputs()); var arguments = AstFactory.BuildExprList(inputs); var inputParams = new List<AssociativeNode> { functionNode, paramNumNode, positionNode, arguments, AstFactory.BuildBooleanNode(true) }; return AstFactory.BuildFunctionCall("_SingleFunctionObject", inputParams); }
public ProtoCore.DSASM.ProcedureNode TraverseDotFunctionCall(ProtoCore.AST.Node node, ProtoCore.AST.Node parentNode, int lefttype, int depth, ref ProtoCore.Type inferedType, ProtoCore.AssociativeGraph.GraphNode graphNode = null, ProtoCore.DSASM.AssociativeSubCompilePass subPass = ProtoCore.DSASM.AssociativeSubCompilePass.kNone, ProtoCore.AST.AssociativeAST.BinaryExpressionNode bnode = null) { FunctionCallNode funcCall = null; ProtoCore.DSASM.ProcedureNode procCallNode = null; ProtoCore.DSASM.ProcedureNode procDotCallNode = null; string procName = null; List<ProtoCore.Type> arglist = new List<ProtoCore.Type>(); ProtoCore.Type dotCallType = new ProtoCore.Type(); dotCallType.UID = (int)PrimitiveType.kTypeVar; dotCallType.IsIndexable = false; bool isConstructor = false; bool isStaticCall = false; bool isStaticCallAllowed = false; bool isUnresolvedDot = false; bool isUnresolvedMethod = false; int classIndex = ProtoCore.DSASM.Constants.kInvalidIndex; string className = string.Empty; ProtoCore.AST.AssociativeAST.FunctionDotCallNode dotCall = node as ProtoCore.AST.AssociativeAST.FunctionDotCallNode; funcCall = dotCall.DotCall; procName = dotCall.FunctionCall.Function.Name; List<AssociativeNode> replicationGuide = (dotCall.FunctionCall.Function as IdentifierNode).ReplicationGuides; var dotCallFirstArgument = dotCall.DotCall.FormalArguments[0]; if (dotCallFirstArgument is FunctionDotCallNode) { isUnresolvedDot = true; } else if (dotCallFirstArgument is IdentifierNode || dotCallFirstArgument is ThisPointerNode) { // Check if the lhs identifer is a class name string lhsName = ""; int ci = Constants.kInvalidIndex; if (dotCallFirstArgument is IdentifierNode) { lhsName = (dotCallFirstArgument as IdentifierNode).Name; ci = compileStateTracker.ClassTable.IndexOf(lhsName); classIndex = ci; className = lhsName; // As a class name can be used as property name, we need to // check if this identifier is a property or a class name. // if (ci != Constants.kInvalidIndex && globalClassIndex != Constants.kInvalidIndex) { ProtoCore.DSASM.SymbolNode symbolnode; bool isAccessbile = false; bool hasAllocated = VerifyAllocation(lhsName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessbile); // Well, found a property whose name is class name. Now // we need to check if the RHS function call is // constructor or not. if (hasAllocated && isAccessbile && symbolnode.functionIndex == ProtoCore.DSASM.Constants.kInvalidIndex) { var procnode = GetProcedureFromInstance(ci, dotCall.FunctionCall); if (procnode != null && !procnode.isConstructor) { ci = Constants.kInvalidIndex; lhsName = ""; } } } } if (ci != ProtoCore.DSASM.Constants.kInvalidIndex) { // It is a class name dotCall.DotCall.FormalArguments[0] = new IntNode { value = ci.ToString() }; dotCallFirstArgument = dotCall.DotCall.FormalArguments[0]; inferedType.UID = dotCallType.UID = ci; string rhsName = dotCall.FunctionCall.Function.Name; procCallNode = GetProcedureFromInstance(ci, dotCall.FunctionCall, graphNode); if (null != procCallNode) { isConstructor = procCallNode.isConstructor; // It's a static call if its not a constructor isStaticCall = !procCallNode.isConstructor; // If this is a static call and the first method found was not static // Look further if (isStaticCall && !procCallNode.isStatic) { ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[ci].GetFirstStaticMemberFunction(procName); if (null != staticProcCallNode) { procCallNode = staticProcCallNode; } } isStaticCallAllowed = procCallNode.isStatic && isStaticCall; } else { ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[ci].GetFirstStaticMemberFunction(procName); string functionName = dotCall.FunctionCall.Function.Name; string property; if (null != staticProcCallNode) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodHasInvalidArguments, functionName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col); } else if (CoreUtils.TryGetPropertyName(functionName, out property)) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticProperty, lhsName, property); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col); } else { string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticMethod, lhsName, functionName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col); } } } if (dotCall.DotCall.FormalArguments.Count == ProtoCore.DSASM.Constants.kDotCallArgCount) { if (dotCallFirstArgument is IdentifierNode) { ProtoCore.DSASM.SymbolNode symbolnode = null; bool isAccessible = false; bool isAllocated = VerifyAllocation((dotCallFirstArgument as IdentifierNode).Name, globalClassIndex, globalProcIndex, out symbolnode, out isAccessible); if (isAllocated && symbolnode.datatype.UID != (int)PrimitiveType.kTypeVar) { inferedType.UID = symbolnode.datatype.UID; if (ProtoCore.DSASM.Constants.kInvalidIndex != inferedType.UID) { procCallNode = GetProcedureFromInstance(symbolnode.datatype.UID, dotCall.FunctionCall); } if (null != procCallNode) { if (procCallNode.isConstructor) { if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { // A constructor cannot be called from an instance string message = String.Format(ProtoCore.BuildData.WarningMessage.KCallingConstructorOnInstance, procName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingConstructorOnInstance, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col); } isUnresolvedDot = true; isUnresolvedMethod = true; } else { isAccessible = procCallNode.access == ProtoCore.DSASM.AccessSpecifier.kPublic || (procCallNode.access == ProtoCore.DSASM.AccessSpecifier.kPrivate && procCallNode.classScope == globalClassIndex); if (!isAccessible) { if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col); } } if (null != procCallNode) { int dynamicRhsIndex = int.Parse((dotCall.DotCall.FormalArguments[1] as IntNode).value); compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].classIndex = procCallNode.classScope; compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].procedureIndex = procCallNode.procId; compileStateTracker.DynamicFunctionTable.functionTable[dynamicRhsIndex].pc = procCallNode.pc; } } } } else { isUnresolvedDot = true; } } else if (dotCallFirstArgument is ThisPointerNode) { if (globalClassIndex != Constants.kInvalidIndex) { procCallNode = GetProcedureFromInstance(globalClassIndex, dotCall.FunctionCall); if (null != procCallNode && procCallNode.isConstructor) { dotCall.DotCall.FormalArguments[0] = new IntNode { value = globalClassIndex.ToString() }; dotCallFirstArgument = dotCall.DotCall.FormalArguments[0]; inferedType.UID = dotCallType.UID = ci; } } } } } else if (funcCall.FormalArguments[0] is IntNode) { inferedType.UID = dotCallType.UID = int.Parse((funcCall.FormalArguments[0] as IntNode).value); classIndex = inferedType.UID; procCallNode = GetProcedureFromInstance(dotCallType.UID, dotCall.FunctionCall, graphNode); if (null != procCallNode) { // It's a static call if its not a constructor isConstructor = procCallNode.isConstructor; isStaticCall = !procCallNode.isConstructor; // If this is a static call and the first method found was not static // Look further if (isStaticCall && !procCallNode.isStatic) { ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstStaticMemberFunction(procName); if (null != staticProcCallNode) { procCallNode = staticProcCallNode; } } isStaticCallAllowed = procCallNode.isStatic && isStaticCall; className = compileStateTracker.ClassTable.ClassNodes[dotCallType.UID].name; if (isStaticCall && !isStaticCallAllowed) { if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { string property; className = compileStateTracker.ClassTable.ClassNodes[dotCallType.UID].name; ProtoCore.DSASM.ProcedureNode staticProcCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstStaticMemberFunction(procName); if (null != staticProcCallNode) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodHasInvalidArguments, procName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col); } else if (CoreUtils.TryGetPropertyName(procName, out property)) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticProperty, property, className); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col); } else { string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingNonStaticMethod, procName, className); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingNonStaticMethodOnClass, message, compileStateTracker.CurrentDSFileName, dotCall.line, dotCall.col); } } isUnresolvedMethod = true; } else { inferedType = procCallNode.returntype; } } } // Its an accceptable method at this point if (!isUnresolvedMethod) { int funtionArgCount = 0; //foreach (AssociativeNode paramNode in funcCall.FormalArguments) for (int n = 0; n < funcCall.FormalArguments.Count; ++n) { AssociativeNode paramNode = funcCall.FormalArguments[n]; ProtoCore.Type paramType = new ProtoCore.Type(); paramType.UID = (int)ProtoCore.PrimitiveType.kTypeVoid; paramType.IsIndexable = false; emitReplicationGuide = false; // If it's a binary node then continue type check, otherwise disable type check and just take the type of paramNode itself // f(1+2.0) -> type check enabled - param is typed as double // f(2) -> type check disabled - param is typed as int enforceTypeCheck = !(paramNode is BinaryExpressionNode); // TODO Jun: Cleansify me // What im doing is just taking the second parameter of the dot op (The method call) // ...and adding it to the graph node dependencies if (ProtoCore.DSASM.Constants.kDotArgIndexDynTableIndex == n) { if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { if (!isConstructor) { if (null != procCallNode) { if (graphNode.dependentList.Count > 0) { ProtoCore.AssociativeGraph.UpdateNodeRef nodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(); ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode(); ProtoCore.DSASM.ProcedureNode procNodeDummy = new ProtoCore.DSASM.ProcedureNode(); if (procCallNode.isAutoGenerated) { ProtoCore.DSASM.SymbolNode sym = new ProtoCore.DSASM.SymbolNode(); sym.name = procName.Remove(0, ProtoCore.DSASM.Constants.kSetterPrefix.Length); updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol; updateNode.symbol = sym; } else { procNodeDummy.name = procName; updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kMethod; updateNode.procNode = procNodeDummy; } graphNode.dependentList[0].updateNodeRefList[0].nodeList.Add(updateNode); } } else { // comment Jun: // This is dotarg whos first argument is also a dotarg // dotarg(dorarg...)...) if (graphNode.dependentList.Count > 0) { if (ProtoCore.Utils.CoreUtils.IsGetterSetter(procName)) { ProtoCore.AssociativeGraph.UpdateNode updateNode = new ProtoCore.AssociativeGraph.UpdateNode(); ProtoCore.DSASM.SymbolNode sym = new ProtoCore.DSASM.SymbolNode(); sym.name = procName.Remove(0, ProtoCore.DSASM.Constants.kSetterPrefix.Length); updateNode.nodeType = ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol; updateNode.symbol = sym; graphNode.dependentList[0].updateNodeRefList[0].nodeList.Add(updateNode); } } } } } } // Traversing the first arg (the LHS pointer/Static instanct/Constructor if (ProtoCore.DSASM.Constants.kDotArgIndexPtr == n) { // Comment Jun: // Allow guides only on 'this' pointers for non getter/setter methods // No guides for 'this' pointers in constructors calls (There is no this pointer yet) // /* class C { def f(a : int) { return = 10; } } p = {C.C(), C.C()}; x = p<1>.f({1,2}<2>); // guides allowed on the pointer 'p' class A { x : var[]; constructor A() { x = {1,2}; } } a = A.A(); b = A.A(); c = a<1>.x<2>; // guides not allowed on getter */ if (!ProtoCore.Utils.CoreUtils.IsGetterSetter(procName) && !isConstructor) { emitReplicationGuide = true; } DfsTraverse(paramNode, ref paramType, false, graphNode, subPass, bnode); if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { if (isStaticCall && isStaticCallAllowed) { Validity.Assert(ProtoCore.DSASM.Constants.kInvalidIndex != classIndex); Validity.Assert(string.Empty != className); SymbolNode classSymbol = new SymbolNode(); classSymbol.name = className; classSymbol.classScope = classIndex; ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode(); dependentNode.PushSymbolReference(classSymbol, ProtoCore.AssociativeGraph.UpdateNodeType.kSymbol); graphNode.PushDependent(dependentNode); } } } // Traversing the actual arguments passed into the function (not the dot function) else if (ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs == n) { int defaultAdded = 0; // If its null this is the second call in a chained dot if (null != procCallNode) { // Check how many args were passed in.... against what is expected defaultAdded = procCallNode.argInfoList.Count - dotCall.FunctionCall.FormalArguments.Count; } // Enable graphnode dependencies if its a setter method bool allowDependentState = null != graphNode ? graphNode.allowDependents : false; if (ProtoCore.Utils.CoreUtils.IsSetter(procName)) { // If the arguments are not temporaries ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ExprListNode; Validity.Assert(1 == exprList.list.Count); string varname = string.Empty; if (exprList.list[0] is IdentifierNode) { varname = (exprList.list[0] as IdentifierNode).Name; // Only allow the acutal function variables and SSA temp vars // TODO Jun: determine what temp could be passed in that is autodegenerated and non-SSA if (!ProtoCore.Utils.CoreUtils.IsAutoGeneratedVar(varname) || ProtoCore.Utils.CoreUtils.IsSSATemp(varname)) { graphNode.allowDependents = true; } } else { graphNode.allowDependents = true; } } emitReplicationGuide = true; if (defaultAdded > 0) { ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ExprListNode; if (subPass != AssociativeSubCompilePass.kUnboundIdentifier) { for (int i = 0; i < defaultAdded; i++) { exprList.list.Add(new DefaultArgNode()); } } DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); funtionArgCount = exprList.list.Count; } else { Validity.Assert(paramNode is ProtoCore.AST.AssociativeAST.ExprListNode); ProtoCore.AST.AssociativeAST.ExprListNode exprList = paramNode as ProtoCore.AST.AssociativeAST.ExprListNode; // Comment Jun: This is a getter/setter or a an auto-generated thisarg function... // ...add the dynamic sv that will be resolved as a pointer at runtime if (!isStaticCall && !isConstructor) { //if (null != procCallNode && ProtoCore.Utils.CoreUtils.IsGetterSetter(procCallNode.name) && AssociativeSubCompilePass.kNone == subPass) // TODO Jun: pls get rid of subPass checking outside the core travesal if (ProtoCore.DSASM.AssociativeSubCompilePass.kNone == subPass) { exprList.list.Insert(0, new DynamicNode()); } } if (exprList.list.Count > 0) { foreach (ProtoCore.AST.AssociativeAST.AssociativeNode exprListNode in exprList.list) { bool repGuideState = emitReplicationGuide; if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { if (exprListNode is ProtoCore.AST.AssociativeAST.ExprListNode || exprListNode is ProtoCore.AST.AssociativeAST.GroupExpressionNode) { if (compileStateTracker.Options.TempReplicationGuideEmptyFlag) { // Emit the replication guide for the exprlist List<ProtoCore.AST.AssociativeAST.AssociativeNode> repGuideList = GetReplicationGuides(exprListNode); EmitReplicationGuides(repGuideList, true); emitReplicationGuide = false; // Pop off the guide if the current element was an array if (null != repGuideList) { EmitInstrConsole(ProtoCore.DSASM.kw.popg); EmitPopGuide(); } } } } else { emitReplicationGuide = false; } DfsTraverse(exprListNode, ref paramType, false, graphNode, subPass, bnode); emitReplicationGuide = repGuideState; } if (subPass != ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { EmitInstrConsole(ProtoCore.DSASM.kw.alloca, exprList.list.Count.ToString()); EmitPopArray(exprList.list.Count); if (exprList.ArrayDimensions != null) { int dimensions = DfsEmitArrayIndexHeap(exprList.ArrayDimensions, graphNode); EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, dimensions.ToString() + "[dim]"); EmitPushArrayIndex(dimensions); } } } else { if (exprList != null) { bool emitReplicationGuideState = emitReplicationGuide; emitReplicationGuide = false; DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); emitReplicationGuide = emitReplicationGuideState; } else { DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); } } funtionArgCount = exprList.list.Count; } emitReplicationGuide = false; // Restore the state only if it is a setter method if (ProtoCore.Utils.CoreUtils.IsSetter(procName)) { graphNode.allowDependents = allowDependentState; } } else if (ProtoCore.DSASM.Constants.kDotArgIndexArgCount == n) { ProtoCore.AST.AssociativeAST.IntNode argNumNode = new ProtoCore.AST.AssociativeAST.IntNode() { value = funtionArgCount.ToString() }; DfsTraverse(argNumNode, ref paramType, false, graphNode, subPass); } else { DfsTraverse(paramNode, ref paramType, false, graphNode, subPass); } emitReplicationGuide = false; enforceTypeCheck = true; arglist.Add(paramType); } } if (subPass == ProtoCore.DSASM.AssociativeSubCompilePass.kUnboundIdentifier) { return null; } // Comment Jun: Append the lhs pointer as an argument to the overloaded function if (!isConstructor && !isStaticCall) { Validity.Assert(dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs] is ExprListNode); ExprListNode functionArgs = dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexArrayArgs] as ExprListNode; functionArgs.list.Insert(0, dotCall.DotCall.FormalArguments[ProtoCore.DSASM.Constants.kDotArgIndexPtr]); } if (isUnresolvedMethod) { EmitNullNode(new NullNode(), ref inferedType); return null; } procDotCallNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotArgMethodName, arglist, codeBlock); // From here on, handle the actual procedure call int type = ProtoCore.DSASM.Constants.kInvalidIndex; int refClassIndex = ProtoCore.DSASM.Constants.kInvalidIndex; if (parentNode != null && parentNode is ProtoCore.AST.AssociativeAST.IdentifierListNode) { ProtoCore.AST.Node leftnode = (parentNode as ProtoCore.AST.AssociativeAST.IdentifierListNode).LeftNode; if (leftnode != null && leftnode is ProtoCore.AST.AssociativeAST.IdentifierNode) { refClassIndex = compileStateTracker.ClassTable.IndexOf(leftnode.Name); } } if (dotCallFirstArgument is FunctionCallNode || dotCallFirstArgument is FunctionDotCallNode || dotCallFirstArgument is ExprListNode) { inferedType.UID = arglist[0].UID; } // If lefttype is a valid class then check if calling a constructor if ((int)ProtoCore.PrimitiveType.kInvalidType != inferedType.UID && (int)ProtoCore.PrimitiveType.kTypeVoid != inferedType.UID && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall) { bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex; procCallNode = compileStateTracker.ClassTable.ClassNodes[inferedType.UID].GetFirstMemberFunction(procName); } // Try function pointer firstly if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)) { bool isAccessibleFp; ProtoCore.DSASM.SymbolNode symbolnode = null; bool isAllocated = VerifyAllocation(procName, globalClassIndex, globalProcIndex, out symbolnode, out isAccessibleFp); if (isAllocated) // not checking the type against function pointer, as the type could be var { procName = ProtoCore.DSASM.Constants.kFunctionPointerCall; // The graph node always depends on this function pointer if (null != graphNode) { ProtoCore.AssociativeGraph.GraphNode dependentNode = new ProtoCore.AssociativeGraph.GraphNode(); dependentNode.PushSymbolReference(symbolnode); graphNode.PushDependent(dependentNode); } } } // Always try global function firstly. Because we dont have syntax // support for calling global function (say, ::foo()), if we try // member function firstly, there is no way to call a global function // For member function, we can use this.foo() to distinguish it from // global function. if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall)) { procCallNode = compileStateTracker.GetFirstVisibleProcedure(procName, arglist, codeBlock); if (null != procCallNode) { type = ProtoCore.DSASM.Constants.kGlobalScope; if (compileStateTracker.TypeSystem.IsHigherRank(procCallNode.returntype.UID, inferedType.UID)) { inferedType = procCallNode.returntype; } } } // Try member functions in global class scope if ((procCallNode == null) && (procName != ProtoCore.DSASM.Constants.kFunctionPointerCall) && (parentNode == null)) { if (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) { int realType; bool isAccessible; bool isStaticOrConstructor = refClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex; ProtoCore.DSASM.ProcedureNode memProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].GetMemberFunction(procName, arglist, globalClassIndex, out isAccessible, out realType, isStaticOrConstructor); if (memProcNode != null) { Debug.Assert(realType != ProtoCore.DSASM.Constants.kInvalidIndex); procCallNode = memProcNode; inferedType = procCallNode.returntype; type = realType; if (!isAccessible) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodIsInaccessible, procName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kAccessViolation, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col); inferedType.UID = (int)PrimitiveType.kTypeNull; EmitPushNull(); return procCallNode; } } } } if (isUnresolvedDot) { // Get the dot call procedure ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode; if (!isConstructor && !isStaticCall) { procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock); } if(CoreUtils.IsGetter(procName)) { EmitFunctionCall(depth, type, arglist, procNode, funcCall, true); } else EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode); if (dotCallType.UID != (int)PrimitiveType.kTypeVar) { inferedType.UID = dotCallType.UID; } return procCallNode; } if (null != procCallNode) { if (procCallNode.isConstructor && (globalClassIndex != ProtoCore.DSASM.Constants.kInvalidIndex) && (globalProcIndex != ProtoCore.DSASM.Constants.kInvalidIndex) && (globalClassIndex == inferedType.UID)) { ProtoCore.DSASM.ProcedureNode contextProcNode = compileStateTracker.ClassTable.ClassNodes[globalClassIndex].vtable.procList[globalProcIndex]; if (contextProcNode.isConstructor && string.Equals(contextProcNode.name, procCallNode.name) && contextProcNode.runtimeIndex == procCallNode.runtimeIndex) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kCallingConstructorInConstructor, procName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kCallingConstructorInConstructor, message, compileStateTracker.CurrentDSFileName, node.line, node.col); inferedType.UID = (int)PrimitiveType.kTypeNull; EmitPushNull(); return procCallNode; } } inferedType = procCallNode.returntype; //if call is replication call if (procCallNode.isThisCallReplication) { inferedType.IsIndexable = true; inferedType.rank++; } // Get the dot call procedure ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode; if (!isConstructor && !isStaticCall) { procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock); } if (CoreUtils.IsSetter(procName)) { EmitFunctionCall(depth, type, arglist, procNode, funcCall); } // Do not emit breakpoint at getters only - pratapa else if (CoreUtils.IsGetter(procName)) { EmitFunctionCall(depth, type, arglist, procNode, funcCall, true); } else { EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode); } if (dotCallType.UID != (int)PrimitiveType.kTypeVar) { inferedType.UID = dotCallType.UID; } if (isConstructor) { foreach (AssociativeNode paramNode in dotCall.FunctionCall.FormalArguments) { // Get the lhs symbol list ProtoCore.Type ltype = new ProtoCore.Type(); ltype.UID = globalClassIndex; ProtoCore.AssociativeGraph.UpdateNodeRef argNodeRef = new ProtoCore.AssociativeGraph.UpdateNodeRef(); DFSGetSymbolList(paramNode, ref ltype, argNodeRef); if (null != graphNode) { graphNode.updatedArguments.Add(argNodeRef); } } graphNode.firstProc = procCallNode; } return procCallNode; } else { // Function does not exist at this point but we try to reolve at runtime if (depth <= 0 && procName != ProtoCore.DSASM.Constants.kFunctionPointerCall) { if (inferedType.UID != (int)PrimitiveType.kTypeVar) { if (!compileStateTracker.Options.SuppressFunctionResolutionWarning) { string property; if (CoreUtils.TryGetPropertyName(procName, out property)) { string message = String.Format(ProtoCore.BuildData.WarningMessage.kPropertyNotFound, property); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kPropertyNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col); } else { string message = String.Format(ProtoCore.BuildData.WarningMessage.kMethodNotFound, procName); buildStatus.LogWarning(ProtoCore.BuildData.WarningID.kFunctionNotFound, message, compileStateTracker.CurrentDSFileName, funcCall.line, funcCall.col); } } inferedType.UID = (int)PrimitiveType.kTypeNull; } // Get the dot call procedure ProtoCore.DSASM.ProcedureNode procNode = procDotCallNode; if (!isConstructor && !isStaticCall) { procNode = compileStateTracker.GetFirstVisibleProcedure(ProtoCore.DSASM.Constants.kDotMethodName, null, codeBlock); } if (CoreUtils.IsGetter(procName)) { EmitFunctionCall(depth, type, arglist, procNode, funcCall, true); } else EmitFunctionCall(depth, type, arglist, procNode, funcCall, false, bnode); if (dotCallType.UID != (int)PrimitiveType.kTypeVar) { inferedType.UID = dotCallType.UID; } } else { if (procName == ProtoCore.DSASM.Constants.kFunctionPointerCall && depth == 0) { ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(procName, arglist, lefttype); compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode); var iNode = nodeBuilder.BuildIdentfier(funcCall.Function.Name); EmitIdentifierNode(iNode, ref inferedType); } else { ProtoCore.DSASM.DynamicFunctionNode dynamicFunctionNode = new ProtoCore.DSASM.DynamicFunctionNode(funcCall.Function.Name, arglist, lefttype); compileStateTracker.DynamicFunctionTable.functionTable.Add(dynamicFunctionNode); } // The function call EmitInstrConsole(ProtoCore.DSASM.kw.callr, funcCall.Function.Name + "[dynamic]"); EmitDynamicCall(compileStateTracker.DynamicFunctionTable.functionTable.Count - 1, globalClassIndex, depth, funcCall.line, funcCall.col, funcCall.endLine, funcCall.endCol); // The function return value EmitInstrConsole(ProtoCore.DSASM.kw.push, ProtoCore.DSASM.kw.regRX); ProtoCore.DSASM.StackValue opReturn = new ProtoCore.DSASM.StackValue(); opReturn.optype = ProtoCore.DSASM.AddressType.Register; opReturn.opdata = (int)ProtoCore.DSASM.Registers.RX; EmitPush(opReturn); if (compileStateTracker.Options.TempReplicationGuideEmptyFlag && emitReplicationGuide) { int guides = EmitReplicationGuides(replicationGuide); EmitInstrConsole(ProtoCore.DSASM.kw.pushindex, guides + "[guide]"); EmitPushReplicationGuide(guides); } //assign inferedType to var inferedType.UID = (int)PrimitiveType.kTypeVar; } } return procDotCallNode; }
public IntNode(IntNode rhs) : base(rhs) { value = rhs.value; }
private void EmitRangeExprNode(AssociativeNode node, ref ProtoCore.Type inferedType, GraphNode graphNode = null, ProtoCore.CompilerDefinitions.Associative.SubCompilePass subPass = ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { RangeExprNode range = node as RangeExprNode; // Do some static checking... var fromNode = range.From; var toNode = range.To; var stepNode = range.Step; var stepOp = range.StepOperator; var hasAmountOperator = range.HasRangeAmountOperator; bool isStepValid = true; string warningMsg = string.Empty; if ((fromNode is IntNode || fromNode is DoubleNode) && (toNode is IntNode || toNode is DoubleNode) && (stepNode == null || stepNode is IntNode || stepNode is DoubleNode)) { double current = (fromNode is IntNode) ? (fromNode as IntNode).Value : (fromNode as DoubleNode).Value; double end = (toNode is IntNode) ? (toNode as IntNode).Value : (toNode as DoubleNode).Value; double step = 1; if (stepNode != null) { step = (stepNode is IntNode) ? (stepNode as IntNode).Value : (stepNode as DoubleNode).Value; } switch (stepOp) { case ProtoCore.DSASM.RangeStepOperator.StepSize: if (!hasAmountOperator) { if (stepNode == null && end < current) { step = -1; } if (step == 0) { isStepValid = false; warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithStepSizeZero; } else if ((end > current && step < 0) || (end < current && step > 0)) { isStepValid = false; warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithInvalidStepSize; } } break; case ProtoCore.DSASM.RangeStepOperator.Number: if (hasAmountOperator) { isStepValid = false; warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithStepSizeZero; } else { if (stepNode != null && stepNode is DoubleNode && subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { buildStatus.LogWarning(WarningID.kInvalidRangeExpression, ProtoCore.Properties.Resources.kRangeExpressionWithNonIntegerStepNumber, core.CurrentDSFileName, stepNode.line, stepNode.col, graphNode); } else if (step <= 0) { isStepValid = false; warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithNegativeStepNumber; } } break; case ProtoCore.DSASM.RangeStepOperator.ApproximateSize: if (hasAmountOperator) { isStepValid = false; warningMsg = ProtoCore.Properties.Resources.kRangeExpressionConflictOperator; } else if (step == 0) { isStepValid = false; warningMsg = ProtoCore.Properties.Resources.kRangeExpressionWithStepSizeZero; } break; default: break; } } if (!isStepValid && subPass == ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kNone) { buildStatus.LogWarning(WarningID.kInvalidRangeExpression, warningMsg, core.CurrentDSFileName, stepNode.line, stepNode.col, graphNode); EmitNullNode(new NullNode(), ref inferedType); return; } // Replace with build-in RangeExpression() function. - Yu Ke bool emitReplicationgGuideState = emitReplicationGuide; emitReplicationGuide = false; IntNode op = null; switch (stepOp) { case RangeStepOperator.StepSize: op = new IntNode(0); break; case RangeStepOperator.Number: op = new IntNode(1); break; case RangeStepOperator.ApproximateSize: op = new IntNode(2); break; default: op = new IntNode(-1); break; } var arguments = new List<AssociativeNode> { fromNode, toNode, stepNode ?? new NullNode(), op, AstFactory.BuildBooleanNode(stepNode != null), AstFactory.BuildBooleanNode(hasAmountOperator), }; var rangeExprFunc = AstFactory.BuildFunctionCall(Constants.kFunctionRangeExpression, arguments); EmitFunctionCallNode(rangeExprFunc, ref inferedType, false, graphNode, subPass); emitReplicationGuide = emitReplicationgGuideState; if (subPass != ProtoCore.CompilerDefinitions.Associative.SubCompilePass.kUnboundIdentifier) { if (range.ArrayDimensions != null) { int dim = DfsEmitArrayIndexHeap(range.ArrayDimensions, graphNode); EmitInstrConsole(kw.pushindex, dim + "[dim]"); EmitPushArrayIndex(dim); } if (emitReplicationGuide) { EmitAtLevel(range.AtLevel); EmitReplicationGuides(range.ReplicationGuides); } } }
public void TestTypeSwitch() { object v = null; object node = null; DoubleNode doubleNode = new DoubleNode(1.2); node = doubleNode; TypeSwitch.Do( node, TypeSwitch.Case<IntNode>(n => v = n.Value), TypeSwitch.Case<DoubleNode>(n => v = n.Value), TypeSwitch.Case<BooleanNode>(n => v = n.Value), TypeSwitch.Case<StringNode>(n => v = n.Value), TypeSwitch.Default(() => v = null)); Assert.AreEqual(v, 1.2); IntNode intNode = new IntNode(42); node = intNode; TypeSwitch.Do( node, TypeSwitch.Case<IntNode>(n => v = n.Value), TypeSwitch.Case<DoubleNode>(n => v = n.Value), TypeSwitch.Case<BooleanNode>(n => v = n.Value), TypeSwitch.Case<StringNode>(n => v = n.Value), TypeSwitch.Default(() => v = null)); Assert.AreEqual(v, 42); StringNode sNode = new StringNode(); node = sNode; TypeSwitch.Do( node, TypeSwitch.Case<IntNode>(n => v = n.Value), TypeSwitch.Case<DoubleNode>(n => v = n.Value), TypeSwitch.Case<BooleanNode>(n => v = n.Value), TypeSwitch.Default(() => v = 24)); Assert.AreEqual(v, 24); }
public static ProtoCore.AST.AssociativeAST.FunctionDotCallNode GenerateCallDotNode(ProtoCore.AST.AssociativeAST.AssociativeNode lhs, ProtoCore.AST.AssociativeAST.FunctionCallNode rhsCall, Core core = null) { // The function name to call string rhsName = rhsCall.Function.Name; int argNum = rhsCall.FormalArguments.Count; ProtoCore.AST.AssociativeAST.ExprListNode argList = new ProtoCore.AST.AssociativeAST.ExprListNode(); foreach (ProtoCore.AST.AssociativeAST.AssociativeNode arg in rhsCall.FormalArguments) { // The function arguments argList.list.Add(arg); } FunctionCallNode funCallNode = new FunctionCallNode(); IdentifierNode funcName = new IdentifierNode { Value = Constants.kDotArgMethodName, Name = Constants.kDotArgMethodName }; funCallNode.Function = funcName; funCallNode.Name = Constants.kDotArgMethodName; NodeUtils.CopyNodeLocation(funCallNode, lhs); int rhsIdx = ProtoCore.DSASM.Constants.kInvalidIndex; string lhsName = string.Empty; if (lhs is ProtoCore.AST.AssociativeAST.IdentifierNode) { lhsName = (lhs as ProtoCore.AST.AssociativeAST.IdentifierNode).Name; if (lhsName == ProtoCore.DSDefinitions.Keyword.This) { lhs = new ProtoCore.AST.AssociativeAST.ThisPointerNode(); } } if (core != null) { DynamicFunction func; if (core.DynamicFunctionTable.TryGetFunction(rhsName, 0, Constants.kInvalidIndex, out func)) { rhsIdx = func.Index; } else { func = core.DynamicFunctionTable.AddNewFunction(rhsName, 0, Constants.kInvalidIndex); rhsIdx = func.Index; } } // The first param to the dot arg (the pointer or the class name) funCallNode.FormalArguments.Add(lhs); // The second param which is the dynamic table index of the function to call var rhs = new IntNode(rhsIdx); funCallNode.FormalArguments.Add(rhs); // The array dimensions ProtoCore.AST.AssociativeAST.ExprListNode arrayDimExperList = new ProtoCore.AST.AssociativeAST.ExprListNode(); int dimCount = 0; if (rhsCall.Function is ProtoCore.AST.AssociativeAST.IdentifierNode) { // Number of dimensions ProtoCore.AST.AssociativeAST.IdentifierNode fIdent = rhsCall.Function as ProtoCore.AST.AssociativeAST.IdentifierNode; if (fIdent.ArrayDimensions != null) { arrayDimExperList = ProtoCore.Utils.CoreUtils.BuildArrayExprList(fIdent.ArrayDimensions); dimCount = arrayDimExperList.list.Count; } else if (rhsCall.ArrayDimensions != null) { arrayDimExperList = ProtoCore.Utils.CoreUtils.BuildArrayExprList(rhsCall.ArrayDimensions); dimCount = arrayDimExperList.list.Count; } else { arrayDimExperList = new ProtoCore.AST.AssociativeAST.ExprListNode(); } } funCallNode.FormalArguments.Add(arrayDimExperList); // Number of dimensions var dimNode = new IntNode(dimCount); funCallNode.FormalArguments.Add(dimNode); if (argNum >= 0) { funCallNode.FormalArguments.Add(argList); funCallNode.FormalArguments.Add(new IntNode(argNum)); } var funDotCallNode = new FunctionDotCallNode(rhsCall); funDotCallNode.DotCall = funCallNode; funDotCallNode.FunctionCall.Function = rhsCall.Function; // Consider the case of "myClass.Foo(a, b)", we will have "DotCall" being // equal to "myClass" (in terms of its starting line/column), and "rhsCall" // matching with the location of "Foo(a, b)". For execution cursor to cover // this whole statement, the final "DotCall" function call node should // range from "lhs.col" to "rhs.col". // NodeUtils.SetNodeEndLocation(funDotCallNode.DotCall, rhsCall); NodeUtils.CopyNodeLocation(funDotCallNode, funDotCallNode.DotCall); return funDotCallNode; }
void Associative_Level(out ProtoCore.AST.AssociativeAST.AssociativeNode node) { node = null; int sign = 1; if (la.kind == 1) { Get(); if(t.val[0] != 'L') { errors.SemErr(t.line, t.col, String.Format(Resources.kInvalidListLevelName, t.val)); } var level = t.val.Remove(0, 1); Int64 value; if (Int64.TryParse(level, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture, out value)) { node = new ProtoCore.AST.AssociativeAST.IntNode(-1*value); } else { errors.SemErr(t.line, t.col, String.Format(Resources.kInvalidListLevelName, t.val)); } NodeUtils.SetNodeLocation(node, t); } else if (la.kind == 2 || la.kind == 15) { if (la.kind == 15) { Get(); sign = -1; } Expect(2); Int64 value; if (Int64.TryParse(t.val, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture, out value)) { node = new ProtoCore.AST.AssociativeAST.IntNode(sign*value); } else { errors.SemErr(t.line, t.col, String.Format(Resources.kInvalidListLevelName, t.val)); } NodeUtils.SetNodeLocation(node, t); } else SynErr(90); }