예제 #1
0
        private float EvaluateExpression(CompilerParser.ExpressionContext ctx)
        {
            float left, right;

            // Если выражение является обычным числом(left, right и sign будут null) - просто возвращаем его
            // В случае с одинокой переменной - читаем из ее значение памяти
            if (ctx.left == null)
            {
                return(ctx.Start.Type == CompilerParser.ID
                    ? (float)CompilerParser.memory[ctx.Start.Text]
                    : Convert.ToSingle(ctx.Start.Text));
            }

            // Если левая часть выражения является переменной - вытаскиваем ее значение
            if (ctx.left.Start.Type == CompilerParser.ID)
            {
                left = Convert.ToSingle(CompilerParser.memory[ctx.left.Start.Text]);
            }
            // Если левая часть выражения тоже является выражением - рекурсивно вычисляем его значение
            else if (ctx.left.left != null)
            {
                left = EvaluateExpression(ctx.left);
            }
            // Если числом (у него левый узел всегда будет null), значит просто конвертируем его в float
            else
            {
                left = Convert.ToSingle(ctx.left.Start.Text);
            }

            // Тоже самое с правой частью, только смотрим на правый узел
            if (ctx.right.Start.Type == CompilerParser.ID)
            {
                right = Convert.ToSingle(CompilerParser.memory[ctx.right.Start.Text]);
            }
            else if (ctx.right.right != null)
            {
                right = EvaluateExpression(ctx.right);
            }
            else
            {
                right = Convert.ToSingle(ctx.right.Start.Text);
            }

            // Выполняем нужное арифметическое действие с операндами и возвращаем результат
            switch (ctx.sign.Text)
            {
            case "/": return(left / right);

            case "*": return(left * right);

            case "+": return(left + right);

            case "-": return(left - right);

            default: throw new Exception($"Incorrect sign '{ctx.sign.Text}'");
            }
        }
예제 #2
0
 /// <summary>
 /// Enter a parse tree produced by <see cref="CompilerParser.expression"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void EnterExpression([NotNull] CompilerParser.ExpressionContext context)
 {
 }
예제 #3
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="CompilerParser.expression"/>.
 /// <para>
 /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
 /// on <paramref name="context"/>.
 /// </para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 /// <return>The visitor result.</return>
 public virtual Result VisitExpression([NotNull] CompilerParser.ExpressionContext context)
 {
     return(VisitChildren(context));
 }
예제 #4
0
 public override CompilerParser VisitExpression([NotNull] CompilerParser.ExpressionContext context)
 {
     // Кидаем результат в специальное поле, чтобы потом получить к нему доступ из контекста
     context.val = EvaluateExpression(context);
     return(null);
 }