public override Value EmitValue(EmitContext context)
        {
            var   assignmentInterrupt = context.InterruptAssignmentScope();
            Value conditionValue      = context.EmitValue(ConditionExpression);

            assignmentInterrupt.Dispose();

            JumpLabel conditionJump = context.Module.CreateLabel();
            JumpLabel exitTrueJump  = context.Module.CreateLabel();

            Value returnValue = context.GetReturnValue(ValueType);

            // We don't want any references outside the flow control to be dirtied conditionally
            context.TopTable.DirtyAllValues();

            context.Module.AddJumpIfFalse(conditionJump, conditionValue);

            context.EmitValueAssignment(returnValue, TrueExpression);

            context.Module.AddJump(exitTrueJump);
            context.Module.LabelJump(conditionJump);

            context.EmitValueAssignment(returnValue, FalseExpression);

            context.Module.LabelJump(exitTrueJump);

            return(returnValue);
        }
Example #2
0
        public JumpLabel PushContinueLabel()
        {
            JumpLabel continueLabel = Module.CreateLabel();

            _continueLabelStack.Push(continueLabel);
            return(continueLabel);
        }
        public override Value EmitValue(EmitContext context)
        {
            // We don't want any references outside the flow control to be dirtied conditionally
            context.TopTable.DirtyAllValues();

            Value returnValue = context.GetReturnValue(ValueType);

            context.EmitValueAssignment(returnValue, Lhs);

            TypeSymbol systemObjectType = context.GetTypeSymbol(SpecialType.System_Object);

            MethodSymbol objectEquality = new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.Equality, systemObjectType, context);

            Value conditionCheck = context.EmitValue(BoundInvocationExpression.CreateBoundInvocation(context, null,
                                                                                                     objectEquality, null,
                                                                                                     new BoundExpression[]
            {
                BoundAccessExpression.BindAccess(returnValue),
                BoundAccessExpression.BindAccess(context.GetConstantValue(systemObjectType, null))
            }));

            JumpLabel notNullLabel = context.Module.CreateLabel();

            context.Module.AddJumpIfFalse(notNullLabel, conditionCheck);

            context.EmitValueAssignment(returnValue, Rhs);

            context.Module.LabelJump(notNullLabel);

            return(returnValue);
        }
Example #4
0
        public JumpLabel PushBreakLabel()
        {
            JumpLabel breakLabel = Module.CreateLabel();

            _breakLabelStack.Push(breakLabel);
            return(breakLabel);
        }
Example #5
0
        public override void Emit(EmitContext context)
        {
            Value conditionValue = context.EmitValue(ConditionExpression);

            JumpLabel exitLabel = context.Module.CreateLabel();
            JumpLabel failLabel = context.Module.CreateLabel();

            context.Module.AddJumpIfFalse(failLabel, conditionValue);

            if (BodyStatement != null)
            {
                context.Emit(BodyStatement);
            }

            if (ElseStatement != null)
            {
                context.Module.AddJump(exitLabel);
            }

            context.Module.LabelJump(failLabel);

            if (ElseStatement != null)
            {
                context.Emit(ElseStatement);
            }

            context.Module.LabelJump(exitLabel);
        }
Example #6
0
        /// <summary>
        /// Hole die relative Sprungadresse des Rückwärtsprungs.
        /// </summary>
        /// <returns>Relative Sprungadresse</returns>
        public int GetJumpBackwardAddress()
        {
            // Label holen.
            JumpLabel jumpLabel = jumpLabelStack.Pop();

            // Relative Sprungadresse berechnen (Ziel - Start ... ergibt negative Zahl bspw. 21 - 42 = -21 = 0xFF FF FF EB)
            // Bei der Startadresse muss noch die Länge des Sprungbefehls (3) aufgerechnet werden.
            // Berechnete Adresse zurück geben.
            return(jumpLabel.jumpTo - (currentCodePosition + 3));
        }
Example #7
0
        /// <summary>
        /// Aktualisiere relative Sprungadresse im Bytecode.
        /// </summary>
        /// <param name="commandSize">Bytes die auf relative Sprungadresse addiert werden müssen</param>
        public void UpdateJumpFoward(int commandSize = 0)
        {
            // Label holen.
            JumpLabel jumpLabel = jumpLabelStack.Pop();
            // Relative Sprungadresse berechnen (Ziel - Start). Wobei das Ziel die nächste Adresse ist (diese ist abhängig von der Größe des Befehls).
            int targetAddress = (currentCodePosition + commandSize) - jumpLabel.jumpFrom;

            // Sprungadresse an entsprechende Stelle nachtragen.
            byte[] byteArray = BitConverter.GetBytes(targetAddress);
            codeBuffer[jumpLabel.jumpLabelPosition]     = byteArray[0];
            codeBuffer[jumpLabel.jumpLabelPosition + 1] = byteArray[1];
        }
Example #8
0
        /// <summary>
        /// Generates the code for a JumpLabel node.
        /// </summary>
        /// <param name="jl">The JumpLabel node.</param>
        /// <returns>String containing C# code for JumpLabel jl.</returns>
        private void GenerateJumpLabel(JumpLabel jl, StringBuilder sb)
        {
            string labelStatement;

            if (m_insertCoopTerminationChecks)
            {
                labelStatement = m_coopTerminationCheck;
            }
            else
            {
                labelStatement = "NoOp();";
            }

            GenerateLine(String.Format("{0}: {1}", CheckName(jl.LabelName), labelStatement), jl, sb);
        }
        public void AddJumpLabel(JumpLabel jumpLabel, string comment = "")
        {
            if (jumpLabel.IsResolved)
            {
                throw new System.Exception($"Target jump label {jumpLabel.uniqueName} has already been used!");
            }

            jumpLabel.resolvedAddress = (uint)programCounter;

#if USE_UDON_LABELS
            AppendCommentedLine($"{jumpLabel.uniqueName}:", comment);
#endif
            //AppendCommentedLine("NOP", comment);
            //programCounter += UdonSharpUtils.GetUdonInstructionSize("NOP");
        }
        public void AddJumpIfFalse(JumpLabel jumpTarget, string comment = "")
        {
#if USE_UDON_LABELS
            AppendCommentedLine($"JUMP_IF_FALSE, {jumpTarget.uniqueName}", comment);
#else
            if (jumpTarget.IsResolved)
            {
                AppendCommentedLine($"JUMP_IF_FALSE, {jumpTarget.AddresStr()}", comment);
            }
            else
            {
                AppendCommentedLine($"JUMP_IF_FALSE_LABEL, [{jumpTarget.uniqueName}]", comment);
            }
#endif

            programCounter += UdonSharpUtils.GetUdonInstructionSize("JUMP_IF_FALSE");
        }
Example #11
0
        public override void Emit(EmitContext context)
        {
            JumpLabel continueLabel = context.PushContinueLabel();
            JumpLabel breakLabel    = context.PushBreakLabel();

            context.Module.LabelJump(continueLabel);

            context.Emit(Body);

            context.Module.AddJumpIfFalse(breakLabel, context.EmitValue(Condition));

            context.Module.AddJump(continueLabel);

            context.Module.LabelJump(breakLabel);

            context.PopBreakLabel();
            context.PopContinueLabel();
        }
Example #12
0
        JumpLabel GetLabel(string labelName, int fileCount)
        {
            if (!_kuexok.ContainsKey(labelName))
            {
                labelName = $"{labelName}@{fileCount}";
            }

            if (_labels.ContainsKey(labelName))
            {
                return(_labels[labelName]);
            }
            else
            {
                var jumpLabel = new JumpLabel();
                _labels.Add(labelName, jumpLabel);
                return(jumpLabel);
            }
        }
Example #13
0
        public override void Emit(EmitContext context)
        {
            using (context.OpenBlockScope())
            {
                if (Declaration != null)
                {
                    context.Emit(Declaration);
                }

                foreach (var initializer in Initializers)
                {
                    context.Emit(initializer);
                }

                JumpLabel continueLabel = context.PushContinueLabel();
                JumpLabel breakLabel    = context.PushBreakLabel();
                JumpLabel loopLabel     = context.Module.CreateLabel();

                context.Module.LabelJump(loopLabel);

                if (Condition != null)
                {
                    context.Module.AddJumpIfFalse(breakLabel, context.EmitValue(Condition));
                }

                context.Emit(Body);

                context.Module.LabelJump(continueLabel);

                foreach (var incrementor in Incrementors)
                {
                    context.Emit(incrementor);
                }

                context.Module.AddJump(loopLabel);

                context.Module.LabelJump(breakLabel);

                context.PopBreakLabel();
                context.PopContinueLabel();
            }
        }
Example #14
0
        public override Value EmitValue(EmitContext context)
        {
            // We don't want any references outside the flow control to be dirtied conditionally
            context.TopTable.DirtyAllValues();

            Value resultValue = context.CreateInternalValue(ValueType);

            if (OperatorType == BuiltinOperatorType.LogicalAnd)
            {
                JumpLabel failLabel = context.Module.CreateLabel();

                context.EmitValueAssignment(resultValue, Lhs);

                context.Module.AddJumpIfFalse(failLabel, resultValue);

                context.EmitValueAssignment(resultValue, Rhs);

                context.Module.LabelJump(failLabel);
            }
            else if (OperatorType == BuiltinOperatorType.LogicalOr)
            {
                JumpLabel failLabel = context.Module.CreateLabel();
                JumpLabel exitLabel = context.Module.CreateLabel();

                context.EmitValueAssignment(resultValue, Lhs);

                context.Module.AddJumpIfFalse(failLabel, resultValue);
                context.Module.AddJump(exitLabel);

                context.Module.LabelJump(failLabel);

                context.EmitValueAssignment(resultValue, Rhs);

                context.Module.LabelJump(exitLabel);
            }
            else
            {
                throw new InvalidOperationException("Invalid operator type");
            }

            return(resultValue);
        }
        private string ReplaceLabels(string assemblyString, LabelTable labelTable)
        {
            StringBuilder newAssemblyBuilder = new StringBuilder();

            using (StringReader reader = new StringReader(assemblyString))
            {
                string currentLine = reader.ReadLine();

                while (currentLine != null)
                {
                    string line = currentLine.TrimStart(_trimChars);
                    if (line.StartsWith("JUMP_LABEL,", StringComparison.Ordinal))
                    {
                        int       startIdx  = line.IndexOf('[') + 1;
                        int       endIdx    = line.IndexOf(']');
                        string    labelName = line.Substring(startIdx, endIdx - startIdx);
                        JumpLabel label     = labelTable.GetLabel(labelName);
                        newAssemblyBuilder.AppendFormat("        JUMP, {0}\n", label.AddresStr());
                    }
                    else if (line.StartsWith("JUMP_IF_FALSE_LABEL,", StringComparison.Ordinal))
                    {
                        int       startIdx  = line.IndexOf('[') + 1;
                        int       endIdx    = line.IndexOf(']');
                        string    labelName = line.Substring(startIdx, endIdx - startIdx);
                        JumpLabel label     = labelTable.GetLabel(labelName);
                        newAssemblyBuilder.AppendFormat("        JUMP_IF_FALSE, {0}\n", label.AddresStr());
                    }
                    else
                    {
                        newAssemblyBuilder.Append(currentLine);
                        newAssemblyBuilder.Append("\n");
                    }

                    currentLine = reader.ReadLine();
                }
            }

            return(newAssemblyBuilder.ToString());
        }
 public void AddJumpIfFalse(JumpLabel jumpTarget, SymbolDefinition conditionSymbol, string comment = "")
 {
     AddPush(conditionSymbol);
     AddJumpIfFalse(jumpTarget, comment);
 }
Example #17
0
 public JumpInstruction(JumpLabel jumpTarget)
 {
     JumpTarget = jumpTarget;
 }
Example #18
0
 public JumpIfFalseInstruction(JumpLabel jumpTarget, Value conditionValue)
 {
     JumpTarget     = jumpTarget;
     ConditionValue = conditionValue;
 }
        protected void CheckStackSize(Value valueCount, EmitContext context)
        {
            using (context.InterruptAssignmentScope())
            {
                Value stack = context.RecursiveStackValue;
                BoundAccessExpression stackAccess = BoundAccessExpression.BindAccess(stack);
                Value stackAddr = context.RecursiveStackAddressValue;
                BoundAccessExpression stackAddrAccess = BoundAccessExpression.BindAccess(stackAddr);

                TypeSymbol arrayType = context.GetTypeSymbol(SpecialType.System_Array);

                context.Module.AddCommentTag("Stack size check");

                // Check stack size and double it if it's not enough
                // We know that doubling once will always be enough since the default size of the stack is the max number of stack values pushed in any method
                PropertySymbol arraySizeProperty = arrayType.GetMember <PropertySymbol>("Length", context);

                TypeSymbol intType = context.GetTypeSymbol(SpecialType.System_Int32);

                Value arraySize =
                    context.EmitValue(BoundAccessExpression.BindAccess(context, SyntaxNode, arraySizeProperty,
                                                                       stackAccess));
                BoundAccessExpression arraySizeAccess = BoundAccessExpression.BindAccess(arraySize);

                Value targetSize = context.EmitValue(CreateBoundInvocation(context, SyntaxNode,
                                                                           new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.Addition, intType, context), null,
                                                                           new BoundExpression[] { stackAddrAccess, BoundAccessExpression.BindAccess(valueCount) }));

                Value isSizeGreaterThan = context.EmitValue(CreateBoundInvocation(context, SyntaxNode,
                                                                                  new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.GreaterThanOrEqual, intType, context), null,
                                                                                  new BoundExpression[]
                {
                    BoundAccessExpression.BindAccess(targetSize),
                    arraySizeAccess,
                }));

                JumpLabel skipResizeLabel = context.Module.CreateLabel();

                context.Module.AddJumpIfFalse(skipResizeLabel, isSizeGreaterThan);

                // Resize logic
                Value constantTwo = context.GetConstantValue(intType, 2);
                Value newSize     = context.EmitValue(CreateBoundInvocation(context, SyntaxNode,
                                                                            new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.Multiplication, intType, context), null,
                                                                            new BoundExpression[]
                {
                    arraySizeAccess,
                    BoundAccessExpression.BindAccess(constantTwo),
                }));

                Value newArray = context.EmitValue(new BoundArrayCreationExpression(SyntaxNode, context,
                                                                                    context.GetTypeSymbol(SpecialType.System_Object).MakeArrayType(context),
                                                                                    new BoundExpression[] { BoundAccessExpression.BindAccess(newSize) }, null));

                MethodSymbol arrayCopyMethod = arrayType.GetMembers <MethodSymbol>("Copy", context)
                                               .First(e => e.Parameters.Length == 3 && e.Parameters[2].Type == intType);

                context.Emit(CreateBoundInvocation(context, null, arrayCopyMethod, null,
                                                   new BoundExpression[]
                {
                    stackAccess,
                    BoundAccessExpression.BindAccess(newArray),
                    BoundAccessExpression.BindAccess(arraySize)
                }));

                context.Module.AddCopy(newArray, stack);

                context.Module.LabelJump(skipResizeLabel);

                context.Module.AddCommentTag("Stack size check end");
            }
        }
Example #20
0
        public override Value EmitValue(EmitContext context)
        {
            JumpLabel returnPoint    = context.Module.CreateLabel();
            Value     returnPointVal =
                context.CreateGlobalInternalValue(context.GetTypeSymbol(SpecialType.System_UInt32));

            context.Module.AddPush(returnPointVal);
            var linkage = context.GetMethodLinkage(Method, !IsBaseCall);

            Value[] parameterValues = GetParameterValues(context);

            Value[] recursiveValues = null;
            bool    isRecursiveCall = context.IsRecursiveMethodEmit;

            Value stackSizeCheckVal = null;

            if (isRecursiveCall)
            {
                EmitContext.MethodLinkage selfLinkage = context.GetMethodLinkage(context.CurrentEmitMethod, false);
                recursiveValues = selfLinkage.ParameterValues;

                stackSizeCheckVal = context.CreateGlobalInternalValue(context.GetTypeSymbol(SpecialType.System_Int32));

                CheckStackSize(stackSizeCheckVal, context);
                PushRecursiveValues(selfLinkage.ParameterValues, context);
            }

            ReleaseCowReferences(context);

            if (isRecursiveCall)
            {
                Value.CowValue[] paramCows = parameterValues.Select(e => e.GetCowValue(context)).ToArray();

                for (int i = 0; i < linkage.ParameterValues.Length; ++i)
                {
                    context.EmitValueAssignment(linkage.ParameterValues[i], BoundAccessExpression.BindAccess(paramCows[i]));
                }

                foreach (var paramCow in paramCows)
                {
                    paramCow.Dispose();
                }
            }
            else
            {
                for (int i = 0; i < linkage.ParameterValues.Length; ++i)
                {
                    context.Module.AddCopy(parameterValues[i], linkage.ParameterValues[i]);
                }
            }

            context.TopTable.DirtyAllValues();

            if (isRecursiveCall)
            {
                Value[] collectedValues = context.CollectRecursiveValues().Where(e => !recursiveValues.Contains(e)).ToArray();

                PushRecursiveValues(collectedValues, context);

                recursiveValues = recursiveValues.Concat(collectedValues).ToArray();

                stackSizeCheckVal.DefaultValue = recursiveValues.Length;
                context.UpdateRecursiveStackMaxSize(recursiveValues.Length);
            }

            context.Module.AddCommentTag($"Calling {Method}");
            context.Module.AddJump(linkage.MethodLabel);

            context.Module.LabelJump(returnPoint);
            returnPointVal.DefaultValue = returnPoint.Address;

            Value recursiveRet = null;

            if (isRecursiveCall)
            {
                if (linkage.ReturnValue != null)
                {
                    recursiveRet = context.CreateInternalValue(linkage.ReturnValue.UserType);
                    context.Module.AddCopy(linkage.ReturnValue, recursiveRet);
                }

                PopRecursiveValues(recursiveValues, context);
            }

            // Handle out/ref parameters
            for (int i = 0; i < Method.Parameters.Length; ++i)
            {
                if (!Method.Parameters[i].IsOut)
                {
                    continue;
                }

                if (isRecursiveCall)
                {
                    throw new CompilerException("U# does not yet support calling user methods with ref/out parameters from methods marked with RecursiveMethod");
                }

                BoundAccessExpression paramAccess = (BoundAccessExpression)ParameterExpressions[i];

                paramAccess.EmitSet(context, BoundAccessExpression.BindAccess(linkage.ParameterValues[i]));
            }

            // Properties need to return the value that they are set to for assignment expressions
            if (IsPropertySetter)
            {
                return(parameterValues.Last());
            }

            if (Method.ReturnType != null)
            {
                if (isRecursiveCall)
                {
                    return(recursiveRet);
                }

                return(linkage.ReturnValue);
            }

            return(null);
        }
Example #21
0
 public LoopData(JumpLabel continueLabel, JumpLabel breakLabel)
 {
     ContinueLabel = continueLabel;
     BreakLabel    = breakLabel;
 }
Example #22
0
 static LkAssembler()
 {
     FASAL_LABEL = new JumpLabel();
 }
 /// <summary>
 ///     Generates the code for a JumpLabel node.
 /// </summary>
 /// <param name="jl">The JumpLabel node.</param>
 /// <returns>String containing C# code for JumpLabel jl.</returns>
 private string GenerateJumpLabel(JumpLabel jl)
 {
     return GenerateLine(Generate(String.Format("{0}:", CheckName(jl.LabelName)), jl) + " NoOp();");
 }
        public SymbolDefinition Invoke(SymbolDefinition[] invokeParams)
        {
            SymbolDefinition methodResult = null;

            System.Type resultSymbolType = null;
            string      lookupSymbolName = null;

            switch (captureFunc)
            {
            case InternalFunc.TypeIDInstance:
            case InternalFunc.TypeIDGeneric:
                resultSymbolType = typeof(long);
                lookupSymbolName = "udonTypeID";
                break;

            case InternalFunc.TypeNameInstance:
            case InternalFunc.TypeNameGeneric:
                resultSymbolType = typeof(string);
                lookupSymbolName = "udonTypeName";
                break;

            default:
                throw new System.ArgumentException("Invalid internal method invocation");
            }

            methodResult = visitorContext.topTable.CreateUnnamedSymbol(resultSymbolType, SymbolDeclTypeFlags.Internal);

            if (captureFunc == InternalFunc.TypeIDInstance ||
                captureFunc == InternalFunc.TypeNameInstance)
            {
                SymbolDefinition invokeSymbol = captureScope.accessSymbol;

                using (ExpressionCaptureScope resultSetterScope = new ExpressionCaptureScope(visitorContext, null))
                {
                    resultSetterScope.SetToLocalSymbol(methodResult);

                    using (ExpressionCaptureScope getInvokeScope = new ExpressionCaptureScope(visitorContext, null))
                    {
                        getInvokeScope.SetToLocalSymbol(invokeSymbol);
                        getInvokeScope.ResolveAccessToken(nameof(VRC.Udon.UdonBehaviour.GetProgramVariable));

                        string symbolName = visitorContext.topTable.GetReflectionSymbol(lookupSymbolName, resultSymbolType).symbolUniqueName;

                        SymbolDefinition invokeResult = getInvokeScope.Invoke(new SymbolDefinition[] { visitorContext.topTable.CreateConstSymbol(typeof(string), symbolName) });

                        JumpLabel exitBranchJump = visitorContext.labelTable.GetNewJumpLabel("exitUdonTypeIdLoc");
                        JumpLabel falseBranchLoc = visitorContext.labelTable.GetNewJumpLabel("falseUdonTypeIdLoc");

                        SymbolDefinition nullCheckSymbol = null;

                        using (ExpressionCaptureScope nullCheckCondition = new ExpressionCaptureScope(visitorContext, null))
                        {
                            nullCheckCondition.SetToMethods(UdonSharpUtils.GetOperators(typeof(object), BuiltinOperatorType.Inequality));
                            nullCheckSymbol = nullCheckCondition.Invoke(new SymbolDefinition[] { invokeResult, visitorContext.topTable.CreateConstSymbol(typeof(object), null) });
                        }

                        visitorContext.uasmBuilder.AddJumpIfFalse(falseBranchLoc, nullCheckSymbol);

                        resultSetterScope.ExecuteSet(captureScope.CastSymbolToType(invokeResult, resultSymbolType, true));
                        visitorContext.uasmBuilder.AddJump(exitBranchJump);

                        // If the value is null
                        visitorContext.uasmBuilder.AddJumpLabel(falseBranchLoc);

                        if (captureFunc == InternalFunc.TypeIDInstance)
                        {
                            resultSetterScope.ExecuteSet(visitorContext.topTable.CreateConstSymbol(typeof(long), 0L));
                        }
                        else
                        {
                            resultSetterScope.ExecuteSet(visitorContext.topTable.CreateConstSymbol(typeof(string), "UnknownType"));
                        }

                        visitorContext.uasmBuilder.AddJumpLabel(exitBranchJump);
                    }
                }
            }
            else
            {
                object resultSymbolValue = null;

                if (captureFunc == InternalFunc.TypeIDGeneric)
                {
                    resultSymbolValue = Internal.UdonSharpInternalUtility.GetTypeID(genericType);
                }
                else if (captureFunc == InternalFunc.TypeNameGeneric)
                {
                    resultSymbolValue = Internal.UdonSharpInternalUtility.GetTypeName(genericType);
                }

                methodResult = visitorContext.topTable.CreateConstSymbol(resultSymbolType, resultSymbolValue);
            }

            using (ExpressionCaptureScope propagateScope = new ExpressionCaptureScope(visitorContext, visitorContext.topCaptureScope))
            {
                propagateScope.SetToLocalSymbol(methodResult);
            }

            return(methodResult);
        }
Example #25
0
        private IList <LkCode> Analyze(IList <string> wordList, int fileCount, out bool isMain)
        {
            List <LkCode> codeList = new List <LkCode>();
            bool          isCI     = false;

            isMain = true;

            for (int i = 0; i < wordList.Count; i++)
            {
                var str = wordList[i];

                if (str == "'c'i")
                {
                    isCI = true;
                }
                else if (str == "'i'c")
                {
                    isCI = false;
                }
                else
                {
                    string label;
                    string head, middle, tail;

                    switch (str)
                    {
                    case "nll":
                        label = wordList[++i];

                        codeList.Add(new LkCode
                        {
                            Mnemonic = LkMnemonic.NLL,
                            Head     = GetLabel(label, fileCount),
                            Tail     = ZERO,
                        });

                        if (wordList[i + 1] == "l'")
                        {
                            throw new ApplicationException($"Wrong label nll {wordList[i]} l'");
                        }
                        break;

                    case "l'":
                        if (i == 0)
                        {
                            throw new ApplicationException($"Wrong label l'");
                        }

                        label = wordList[++i];

                        codeList.Insert(codeList.Count - 1, new LkCode
                        {
                            Mnemonic = LkMnemonic.NLL,
                            Head     = GetLabel(label, fileCount),
                            Tail     = ZERO,
                        });
                        break;

                    case "kue":
                        ++i;
                        isMain = false;
                        break;

                    case "xok":
                        ++i;
                        break;

                    case "lifem":
                    case "lifem8":
                    case "lifem16":
                        Operand opd = Convert(wordList[++i], fileCount);

                        if (opd is JumpLabel jumpLabel)
                        {
                            var lifemValueLabel = new JumpLabel();

                            codeList.Add(new LkCode
                            {
                                Mnemonic = LkMnemonic.NLL,
                                Head     = lifemValueLabel,
                                Tail     = ZERO,
                            });
                            codeList.Add(new LkCode
                            {
                                Mnemonic = Enum.Parse <LkMnemonic>(str, true),
                                Head     = ZERO,
                                Tail     = ZERO,
                            });
                            _labelLifemList.Add(new LkCode
                            {
                                Mnemonic = str switch
                                {
                                    "lifem8" => LkMnemonic.KRZ8C,
                                    "lifem16" => LkMnemonic.KRZ16C,
                                    _ => LkMnemonic.KRZ,
                                },
                                Head = jumpLabel,
                                Tail = Seti(lifemValueLabel),
                            });
Example #26
0
 /// <summary>
 /// Generates the code for a JumpLabel node.
 /// </summary>
 /// <param name="jl">The JumpLabel node.</param>
 /// <returns>String containing C# code for JumpLabel jl.</returns>
 private string GenerateJumpLabel(JumpLabel jl)
 {
     return(Generate(String.Format("{0}:", CheckName(jl.LabelName)), jl) + " NoOp();\n");
 }
Example #27
0
        public override void Emit(EmitContext context)
        {
            var blockScope = context.OpenBlockScope();

            TypeSymbol intType = context.GetTypeSymbol(SpecialType.System_Int32);

            MethodSymbol   toCharArrayMethod = context.GetTypeSymbol(SpecialType.System_String).GetMembers <MethodSymbol>("ToCharArray", context).First(e => e.Parameters.Length == 0);
            PropertySymbol lengthProperty    = context.GetTypeSymbol(SpecialType.System_Array).GetMember <PropertySymbol>("Length", context);

            Value iteratorValue = context.EmitValue(BoundInvocationExpression.CreateBoundInvocation(context, SyntaxNode, toCharArrayMethod, IteratorSource, new BoundExpression[] {}));

            iteratorValue.MarkUsedRecursively();
            var iteratorAccess = BoundAccessExpression.BindAccess(iteratorValue);

            Value arraySize = context.CreateInternalValue(intType);

            arraySize.MarkUsedRecursively();

            BoundAccessExpression getLength = BoundAccessExpression.BindAccess(context, SyntaxNode, lengthProperty, iteratorAccess);

            context.EmitValueAssignment(arraySize, getLength);

            // Declare and reset incrementor value
            Value incrementorValue = context.CreateInternalValue(intType);

            incrementorValue.MarkUsedRecursively();
            context.EmitValueAssignment(incrementorValue, BoundAccessExpression.BindAccess(context.GetConstantValue(intType, 0)));

            JumpLabel loopLabel = context.Module.CreateLabel();

            context.Module.LabelJump(loopLabel);

            var incrementorAccess = BoundAccessExpression.BindAccess(incrementorValue);

            BoundExpression increment = new BoundInvocationExpression.BoundPrefixOperatorExpression(context, SyntaxNode,
                                                                                                    incrementorAccess, new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.Addition, intType, context));

            var lengthCheck = BoundInvocationExpression.CreateBoundInvocation(context, SyntaxNode,
                                                                              new ExternSynthesizedOperatorSymbol(BuiltinOperatorType.LessThan, intType, context), null,
                                                                              new BoundExpression[]
            {
                incrementorAccess,
                BoundAccessExpression.BindAccess(arraySize)
            });

            JumpLabel exitLoopLabel = context.PushBreakLabel();
            JumpLabel continueLabel = context.PushContinueLabel();

            Value lengthCheckResult = context.EmitValue(lengthCheck);

            context.Module.AddJumpIfFalse(exitLoopLabel, lengthCheckResult);

            context.EmitValueAssignment(context.GetUserValue(ValueSymbol),
                                        BoundAccessExpression.BindElementAccess(context, SyntaxNode, iteratorAccess,
                                                                                new BoundExpression[] { incrementorAccess }));

            context.Emit(BodyStatement);

            context.Module.LabelJump(continueLabel);

            context.Emit(increment);

            context.Module.AddJump(loopLabel);

            context.Module.LabelJump(exitLoopLabel);

            context.PopBreakLabel();
            context.PopContinueLabel();

            blockScope.Dispose();
        }