コード例 #1
0
        public override Value VisitVariableExpression([NotNull] VariableExpressionContext context)
        {
            string varName = context.Name;

            if (!NamedValues.TryGetValue(varName, out Value value))
            {
                throw new ArgumentException("Unknown variable name", nameof(context));
            }

            return(value);
        }
コード例 #2
0
        public override IAstNode VisitVariableExpression([NotNull] VariableExpressionContext context)
        {
            string varName = context.Name;

            if (!NamedValues.TryGetValue(varName, out IVariableDeclaration declaration))
            {
                throw new CodeGeneratorException($"Unknown variable name: {varName}");
            }

            return(new VariableReferenceExpression(context.GetSourceSpan( ), declaration));
        }
コード例 #3
0
ファイル: AstBuilder.cs プロジェクト: stjordanis/Llvm.NET-1
        public override IAstNode VisitVariableExpression(VariableExpressionContext context)
        {
            string varName = context.Name;

            if (!NamedValues.TryGetValue(varName, out IVariableDeclaration? declaration))
            {
                return(new ErrorNode(context.GetSourceSpan( ), $"Unknown variable name: {varName}"));
            }

            return(new VariableReferenceExpression(context.GetSourceSpan( ), declaration));
        }
コード例 #4
0
ファイル: CodeGenerator.cs プロジェクト: nbsn2/Llvm.NET
        public override Value VisitVariableExpression([NotNull] VariableExpressionContext context)
        {
            string varName = context.Name;

            if (!NamedValues.TryGetValue(varName, out Alloca value))
            {
                throw new ArgumentException("Unknown variable name", nameof(context));
            }

            return(InstructionBuilder.Load(value)
                   .RegisterName(varName));
        }
コード例 #5
0
        private Alloca LookupVariable(string name)
        {
            if (!NamedValues.TryGetValue(name, out Alloca? value))
            {
                // Source input is validated by the parser and AstBuilder, therefore
                // this is the result of an internal error in the generator rather
                // then some sort of user error.
                throw new CodeGeneratorException($"ICE: Unknown variable name: {name}");
            }

            return(value);
        }
コード例 #6
0
        public override Value Visit(VariableReferenceExpression reference)
        {
            if (!NamedValues.TryGetValue(reference.Name, out Value value))
            {
                // Source input is validated by the parser and AstBuilder, therefore
                // this is the result of an internal error in the generator rather
                // then some sort of user error.
                throw new CodeGeneratorException($"ICE: Unknown variable name: {reference.Name}");
            }

            return(value);
        }
コード例 #7
0
ファイル: CodeGenerator.cs プロジェクト: nbsn2/Llvm.NET
        public override Value VisitAssignmentExpression([NotNull] AssignmentExpressionContext context)
        {
            var rhs = context.Value.Accept(this);

            if (rhs == null)
            {
                return(null);
            }

            if (!NamedValues.TryGetValue(context.VariableName, out Alloca varSlot))
            {
                throw new ArgumentException("Unknown variable name");
            }

            InstructionBuilder.Store(rhs, varSlot);
            return(rhs);
        }
コード例 #8
0
ファイル: CodeGenerator.cs プロジェクト: nbsn2/Llvm.NET
        /*
         * // Output for-loop as:
         * //   ...
         * //   start = startexpr
         * //   goto loop
         * // loop:
         * //   variable = phi [start, loopheader], [nextvariable, loopend]
         * //   ...
         * //   bodyexpr
         * //   ...
         * // loopend:
         * //   step = stepexpr
         * //   nextvariable = variable + step
         * //   endcond = endexpr
         * //   br endcond, loop, endloop
         * // outloop:
         */
        public override Value VisitForExpression([NotNull] ForExpressionContext context)
        {
            var    function  = InstructionBuilder.InsertBlock.ContainingFunction;
            string varName   = context.Initializer.Name;
            var    allocaVar = CreateEntryBlockAlloca(function, varName);

            // Emit the start code first, without 'variable' in scope.
            Value startVal = null;

            if (context.Initializer.Value != null)
            {
                startVal = context.Initializer.Value.Accept(this);
                if (startVal == null)
                {
                    return(null);
                }
            }
            else
            {
                startVal = Context.CreateConstant(0.0);
            }

            // store the value into allocated location
            InstructionBuilder.Store(startVal, allocaVar);

            // Make the new basic block for the loop header, inserting after current
            // block.
            var preHeaderBlock = InstructionBuilder.InsertBlock;
            var loopBlock      = Context.CreateBasicBlock("loop", function);

            // Insert an explicit fall through from the current block to the loopBlock.
            InstructionBuilder.Branch(loopBlock);

            // Start insertion in loopBlock.
            InstructionBuilder.PositionAtEnd(loopBlock);

            // Start the PHI node with an entry for Start.
            var variable = InstructionBuilder.PhiNode(Context.DoubleType)
                           .RegisterName(varName);

            variable.AddIncoming(startVal, preHeaderBlock);

            // Within the loop, the variable is defined equal to the PHI node.  If it
            // shadows an existing variable, we have to restore it, so save it now.
            NamedValues.TryGetValue(varName, out Alloca oldValue);
            NamedValues[varName] = allocaVar;

            // Emit the body of the loop.  This, like any other expr, can change the
            // current BB.  Note that we ignore the value computed by the body, but don't
            // allow an error.
            if (context.BodyExpression.Accept(this) == null)
            {
                return(null);
            }

            Value stepValue = Context.CreateConstant(1.0);

            // DEBUG: How does ANTLR represent optional context (Null or IsEmpty == true)
            if (context.StepExpression != null)
            {
                stepValue = context.StepExpression.Accept(this);
                if (stepValue == null)
                {
                    return(null);
                }
            }

            // Compute the end condition.
            Value endCondition = context.EndExpression.Accept(this);

            if (endCondition == null)
            {
                return(null);
            }

            var curVar = InstructionBuilder.Load(allocaVar)
                         .RegisterName(varName);
            var nextVar = InstructionBuilder.FAdd(curVar, stepValue)
                          .RegisterName("nextvar");

            InstructionBuilder.Store(nextVar, allocaVar);

            // Convert condition to a bool by comparing non-equal to 0.0.
            endCondition = InstructionBuilder.Compare(RealPredicate.OrderedAndNotEqual, endCondition, Context.CreateConstant(1.0))
                           .RegisterName("loopcond");

            // Create the "after loop" block and insert it.
            var loopEndBlock = InstructionBuilder.InsertBlock;
            var afterBlock   = Context.CreateBasicBlock("afterloop", function);

            // Insert the conditional branch into the end of LoopEndBB.
            InstructionBuilder.Branch(endCondition, loopBlock, afterBlock);
            InstructionBuilder.PositionAtEnd(afterBlock);

            // Add a new entry to the PHI node for the backedge.
            variable.AddIncoming(nextVar, loopEndBlock);

            // Restore the unshadowed variable.
            if (oldValue != null)
            {
                NamedValues[varName] = oldValue;
            }
            else
            {
                NamedValues.Remove(varName);
            }

            // for expr always returns 0.0 for consistency, there is no 'void'
            return(Context.DoubleType.GetNullValue( ));
        }
コード例 #9
0
 /// <inheritdoc/>
 public override object?this[string name] => NamedValues.TryGetValue(name, out object?value) ? value : throw new IndexOutOfRangeException();