Exemplo n.º 1
0
        public IncludeStatement(EvaluationStatement target, StatementInfo info)
        {
            Target = target;
            Info   = info;

            TraversableChildren = StatementHelpers.CreateChildren(target);
        }
Exemplo n.º 2
0
        private void _setFlag(CommandContext context, CompilerFlags flags,
                              Expression <Func <CompilerFlags, object> > prop, string switchName)
        {
            Switch s;

            if ((s = context.GetSwitch(switchName)) != null)
            {
                s.AssertValue();

                var lambda     = prop as LambdaExpression;
                var memberExpr = lambda.Body as MemberExpression;
                if (memberExpr == null)
                {
                    throw new InvalidOperationException();
                }
                var propName = memberExpr.Member.Name;

                var propInfo = flags.GetType().GetProperty(propName);

                if (propInfo.PropertyType == typeof(bool))
                {
                    StatementHelpers.TryParseBooleanFromString(s.Value, out var value);
                    propInfo.SetValue(flags, value);
                }
                else
                {
                    propInfo.SetValue(flags, Convert.ChangeType(s.Value, propInfo.PropertyType));
                }
            }
        }
Exemplo n.º 3
0
        public ReturnStatement(EvaluationStatement result, StatementInfo info)
        {
            Result = result;
            Info   = info;

            TraversableChildren = StatementHelpers.CreateChildren(result);
        }
        public ConditionalBlockStatement(EvaluationStatement condition, IStatement statement, StatementInfo info)
        {
            Condition = condition;
            Statement = statement;
            Info      = info;

            TraversableChildren = StatementHelpers.CreateChildren(condition, statement);
        }
Exemplo n.º 5
0
        public IndexerAccessStatement(EvaluationStatement source, EvaluationStatement indexer, StatementInfo info)
        {
            Source  = source;
            Indexer = indexer;
            Info    = info;

            TraversableChildren = StatementHelpers.CreateChildren(source, indexer);
        }
Exemplo n.º 6
0
        public ForEachStatement(IStatement variable, EvaluationStatement iterator, IStatement statement, StatementInfo info)
        {
            Variable  = variable;
            Iterator  = iterator;
            Statement = statement;
            Info      = info;

            TraversableChildren = StatementHelpers.CreateChildren(variable, iterator, statement);
        }
Exemplo n.º 7
0
        public AssignmentStatement(EvaluationStatement leftSide, EvaluationStatement rightSide,
                                   StatementInfo info, IStatement parentStatement = null)
        {
            LeftSide        = leftSide;
            RightSide       = rightSide;
            Info            = info;
            ParentStatement = parentStatement;

            TraversableChildren = StatementHelpers.CreateChildren(leftSide, rightSide);
        }
        public override string FormatConstantExpression(ExpressionBuilderParams p, TypeDescriptor typeDescriptor,
                                                        string expression,
                                                        EvaluationStatement template)
        {
            if (template is ConstantValueStatement constantValueStatement)
            {
                if (typeDescriptor.IsBoolean())
                {
                    if (!StatementHelpers.TryParseBooleanFromString(constantValueStatement.Value, out var boolResult))
                    {
                        throw new InvalidStatementStructureCompilerException(template, template.Info);
                    }

                    return(boolResult ? "1" : "0");
                }

                if (constantValueStatement.IsString() || constantValueStatement.IsDelegate())
                {
                    if (template.ParentStatement is ArithmeticEvaluationStatement arithmeticEvaluationStatement)
                    {
                        if (arithmeticEvaluationStatement.Operator is AdditionOperator)
                        {
                            if (p.FormatString)
                            {
                                return(BashTranspilerHelpers.ToBashString(constantValueStatement.Value, true, false));
                            }
                        }
                        else
                        {
                            throw new InvalidStatementStructureCompilerException(arithmeticEvaluationStatement,
                                                                                 arithmeticEvaluationStatement.Info);
                        }
                    }

                    return(base.FormatConstantExpression(p, typeDescriptor, expression, template));
                }
            }

            return(base.FormatConstantExpression(p, typeDescriptor, expression, template));
        }
        public static bool ValidateParameters(Context context, Scope scope,
                                              FunctionParameterDefinitionStatement[] schemeParameters, EvaluationStatement[] parameters,
                                              out Exception exception
                                              )
        {
            var passedCount   = parameters?.Length ?? 0;
            var expectedCount = schemeParameters?.Length ?? 0;

            if (passedCount != expectedCount)
            {
                exception = new InvalidFunctionCallParametersCompilerException(expectedCount, passedCount, null);
                return(false);
            }

            if (parameters != null && schemeParameters != null)
            {
                for (var i = 0; i < parameters.Length; i++)
                {
                    var passed = parameters[i];
                    var scheme = schemeParameters[i];

                    var passedType = passed.GetDataType(context, scope);
                    if (!StatementHelpers.IsAssignableFrom(context, scope, scheme.TypeDescriptor, passedType))
                    {
                        if (scheme.DynamicType)
                        {
                            continue;
                        }

                        exception = new TypeMismatchCompilerException(passedType, scheme.TypeDescriptor, passed.Info);
                        return(false);
                    }
                }
            }

            exception = null;
            return(true);
        }
Exemplo n.º 10
0
        private bool CalculatePreProcessorCondition(Token token, IPeekingEnumerator <Token> enumerator,
                                                    ParserContext context, bool parseCondition)
        {
            if (!enumerator.MoveNext())
            {
                throw EndOfFile(token, context);
            }

            token = enumerator.Current;
            if (token.Type != TokenType.OpenParenthesis)
            {
                throw UnexpectedToken(token, context, true);
            }

            if (!enumerator.MoveNext()) //read the first eval token
            {
                throw EndOfFile(token, context);
            }

            token = enumerator.Current;

            var evalStatement = Parser.ReadEvaluationStatement(token, enumerator, context);

            if (!enumerator.MoveNext()) //read the close parenthesis
            {
                throw EndOfFile(token, context);
            }

            token = enumerator.Current;
            if (token.Type != TokenType.CloseParenthesis)
            {
                throw UnexpectedToken(token, context);
            }

            if (parseCondition)
            {
                try
                {
                    var stt = EvaluationStatementTranspilerBase.ProcessEvaluation(Context, Context.GeneralScope,
                                                                                  evalStatement);

                    if (stt is ConstantValueStatement constantValueStatement)
                    {
                        if (StatementHelpers.TryParseBooleanFromString(constantValueStatement.Value, out var boolVal))
                        {
                            return(boolVal);
                        }

                        throw UnexpectedToken(token, context);
                    }
                }
                catch (IdentifierNotFoundCompilerException)
                {
                    return(false);
                }

                throw UnexpectedToken(token, context);
            }

            return(false);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="context"></param>
        /// <param name="scope"></param>
        /// <param name="assertTypeDescriptor"></param>
        /// <param name="statement"></param>
        /// <returns>
        /// 0: success
        /// 1: fail
        /// 2: void return
        /// </returns>
        /// <exception cref="TypeMismatchCompilerException"></exception>
        public static (int, IStatement) CheckReturnOnAllPaths(Context context, Scope scope,
                                                              TypeDescriptor assertTypeDescriptor, IStatement statement)
        {
            switch (statement)
            {
            case ThrowStatement _:
            {
                return(0, null);
            }

            case ReturnStatement returnStatement:
            {
                if (returnStatement.Result == null)
                {
                    return(2, returnStatement);
                }

                var returnDataType = returnStatement.Result.GetDataType(context, scope);
                StatementHelpers.AssertAssignableFrom(context, scope, assertTypeDescriptor, returnDataType,
                                                      returnStatement.Result.Info);
//                    if (!StatementHelpers.IsAssignableFrom(context, scope, assertTypeDescriptor, returnDataType))
//                    {
//                        throw new TypeMismatchCompilerException(returnDataType, assertTypeDescriptor,
//                            returnStatement.Result.Info);
//                    }

                return(0, null);
            }

            case IBranchWrapperStatement branchWrapperStatement:
            {
                foreach (var branch in branchWrapperStatement.Branches)
                {
                    var result = CheckReturnOnAllPaths(context, scope, assertTypeDescriptor, branch);
                    if (result.Item1 != 0)
                    {
                        return(result);
                    }
                }

                return(0, null);
            }

            case IBlockWrapperStatement blockWrapperStatement:
            {
                return(CheckReturnOnAllPaths(context, scope, assertTypeDescriptor, blockWrapperStatement.Statement));
            }

            case BlockStatement block:
            {
                var isUnreachable = false;
                foreach (var stt in block.Statements)
                {
                    if (isUnreachable)
                    {
                        context.WarningWriter.WriteLine(
                            $"Statement {stt.Info} is unreachable");
                        break;
                    }

                    var check = CheckReturnOnAllPaths(context, scope, assertTypeDescriptor, stt);
                    if (check.Item1 == 0)
                    {
                        isUnreachable = true;
                        continue;
                    }
                    else if (check.Item1 == 2)
                    {
                        return(check);
                    }
                }

                return(isUnreachable ? 0 : 1, block);
            }

            default:
                return(1, statement);
            }
        }
Exemplo n.º 12
0
        private static Term GetNextTerm(TokenType endType, int numOfLeftB, int numOfRightB, ref Stack <Term> SS, bool decl = false)
        {
            var      token   = MainFSM.GetNextToken();
            TermType type    = TermType.error;
            Term     newTerm = new Term();

            #region Term type by token
            switch (token.Type)
            {
            case TokenType.exrType:
                type = TermType.not;
                break;

            case TokenType.decNumberType:
            case TokenType.hexNumberType:
            case TokenType.octNumberType:
            case TokenType.charType:
            case TokenType.idType:
            case TokenType.longType:
            case TokenType.sizeofType:
            case TokenType.stringType:
                type = TermType.id;
                break;

            case TokenType.asgnType:
                type = TermType.asgn;
                break;

            case TokenType.procType:
                type = TermType.mod;
                break;

            case TokenType.ampType:
                type = TermType.binAnd;
                break;

            case TokenType.andType:
                type = TermType.logAnd;
                break;

            case TokenType.starType:
                type = TermType.mul;
                break;

            case TokenType.plusType:
                type = TermType.plus;
                break;

            case TokenType.incrType:
                type = TermType.inc;
                break;

            case TokenType.minusType:
                type = TermType.minus;
                break;

            case TokenType.decrType:
                type = TermType.dec;
                break;

            case TokenType.divType:
                type = TermType.div;
                break;

            case TokenType.tElseType:
                type = TermType.cElse;
                break;

            case TokenType.leftRBType:
                type = TermType.leftBr;
                break;

            case TokenType.rightRBType:
                type = TermType.rightBr;
                break;

            case TokenType.lessType:
                type = TermType.less;
                break;

            case TokenType.leftType:
                type = TermType.left;
                break;

            case TokenType.lessEqType:
                type = TermType.lessEq;
                break;

            case TokenType.eqEqType:
                type = TermType.eq;
                break;

            case TokenType.grtType:
                type = TermType.grt;
                break;

            case TokenType.grtEqType:
                type = TermType.grtEq;
                break;

            case TokenType.rightType:
                type = TermType.right;
                break;

            case TokenType.tIfType:
                type = TermType.cCond;
                break;

            case TokenType.xorType:
                type = TermType.xor;
                break;

            case TokenType.bOrType:
                type = TermType.binOr;
                break;

            case TokenType.lOrType:
                type = TermType.logOr;
                break;

            case TokenType.plusEqType:
                type = TermType.plusEq;
                break;

            case TokenType.minusEqType:
                type = TermType.minusEq;
                break;

            case TokenType.multEqType:
                type = TermType.mulEq;
                break;

            case TokenType.divEqType:
                type = TermType.divEq;
                break;

            case TokenType.procEq:
                type = TermType.modEq;
                break;

            case TokenType.rightEqType:
                type = TermType.rightEq;
                break;

            case TokenType.leftEqType:
                type = TermType.leftEq;
                break;

            case TokenType.ampEqType:
                type = TermType.andEq;
                break;

            case TokenType.xorEqType:
                type = TermType.xorEq;
                break;

            case TokenType.bOrEqType:
                type = TermType.orEq;
                break;

            case TokenType.bNotType:
                type = TermType.compl;
                break;

            case TokenType.exrEqType:
                type = TermType.negEq;
                break;

            case TokenType.leftABType:
                type = TermType.leftABtype;
                break;
            }
            #endregion

            if ((endType == TokenType.rightCBType ||
                 endType == TokenType.rightRBType) &&
                token.Type == TokenType.comType &&
                (numOfLeftB == numOfRightB))
            {
                type = TermType.end;
            }

            if (endType == TokenType.semiType && decl && token.Type == TokenType.comType)
            {
                type = TermType.end;
            }

            if (token.Type == endType && (numOfLeftB == numOfRightB))
            {
                type = TermType.end;
            }

            if (token.Type == TokenType.leftCBType)
            {
                MainFSM.Index--;
                var array = new ADVariable()
                {
                    Type = ADVariable.VarType.array
                };
                array.ArrayDimensions.Add(new ADArrayDimension());

                StatementHelpers.ArrayValuesDeclaration(array, 0);

                type = TermType.id;

                array.STRecord = new STRecord {
                    Access = STAccess.local, Name = array.Name, Type = STType.array
                };
                newTerm.Expression = array;
                newTerm.STRecord   = array.STRecord;

                var declaration = new ADVariableDeclarations();
                declaration.Variables.Add(array);
                (AnonymousDeclarations as List <IADNode>).Add(declaration);
            }

            if (type != TermType.error)
            {
                if (token.Type == TokenType.decNumberType ||
                    token.Type == TokenType.hexNumberType ||
                    token.Type == TokenType.octNumberType ||
                    token.Type == TokenType.charType)
                {
                    string newId = Guid.NewGuid().ToString("N");

                    newTerm.STRecord.Name  = newId;
                    newTerm.STRecord.Value = token.Attribute;
                    newTerm.STRecord.Type  = STType.constant;
                }
                else if (token.Type == TokenType.stringType)
                {
                    string newId = Guid.NewGuid().ToString("N");
                    newTerm.STRecord.Name   = newId;
                    newTerm.STRecord.Value  = token.Attribute;
                    newTerm.STRecord.Type   = STType.str;
                    newTerm.STRecord.Access = STAccess.local;

                    var array = new ADVariable
                    {
                        STRecord = newTerm.STRecord,
                        Name     = newId,
                        Type     = ADVariable.VarType.array
                    };

                    if (MainFSM.PeekNextToken().Type == TokenType.leftABType)
                    {
                        var arrayValue = new ADArrayValue()
                        {
                            STRecord = newTerm.STRecord
                        };
                        arrayValue.ComputeIndexes();

                        newTerm.Expression = arrayValue;
                    }

                    var declaration = new ADVariableDeclarations();
                    declaration.Variables.Add(array);
                    (AnonymousDeclarations as List <IADNode>).Add(declaration);
                }
                else if (token.Type == TokenType.idType)
                {
                    var stRecord = ParserFunctions.STSearch(token.Attribute);

                    if (stRecord == null)
                    {
                        if (MainFSM.PeekNextToken().Type == TokenType.leftRBType)
                        {
                            stRecord = ParserFunctions.STablesStack.Peek().Records.Where(m => m.Name == token.Attribute).FirstOrDefault();

                            if (stRecord == null)
                            {
                                stRecord = new STRecord()
                                {
                                    Name = token.Attribute, Type = STType.function
                                };
                            }
                        }

                        if (stRecord == null)
                        {
                            ParserFunctions.SemanticError($"Promenna \'{token.Attribute}\' nebyla deklarovana.");
                        }
                    }

                    if (stRecord.Type == STType.function)
                    {
                        if (SS.Peek().Type == TermType.reference)
                        {
                            stRecord.Address = stRecord.Name;
                            var variable = new ADVariable()
                            {
                                Name = stRecord.Name, STRecord = stRecord, Type = ADVariable.VarType.function
                            };
                            newTerm.Expression = variable;
                        }
                        else
                        {
                            var fceCall = ParserFunctions.fce_call(token.Attribute);
                            fceCall.STRecord   = stRecord;
                            newTerm.Expression = fceCall;
                        }
                    }

                    newTerm.STRecord = stRecord;
                }
                else if (token.Type == TokenType.sizeofType)
                {
                    if (MainFSM.GetNextToken().Type != TokenType.leftRBType)
                    {
                        ParserFunctions.SyntaxError("Byl ocekavan znak \'(\'");
                    }

                    if (MainFSM.GetNextToken().Type != TokenType.longType)
                    {
                        ParserFunctions.SyntaxError("Bylo ocekavano klicove slovo \'long\'");
                    }

                    if (MainFSM.GetNextToken().Type != TokenType.rightRBType)
                    {
                        ParserFunctions.SyntaxError("Byl ocekavan znak \')\'");
                    }
                    newTerm.Expression = new ADSizeOfValue();
                    type = TermType.id;
                }

                newTerm.Type = type;
                return(newTerm);
            }
            else
            {
                ParserFunctions.SyntaxError("Chyba ve vyrazu.");
                return(null);
            }
        }
        public override void WriteBlock(Context context, Scope scope, TextWriter writer,
                                        TextWriter metaWriter,
                                        IStatement statement)
        {
            if (!(statement is VariableDefinitionStatement varDefStt))
            {
                throw new InvalidOperationException();
            }

            if (varDefStt.IsConstant)
            {
                if (!varDefStt.HasDefaultValue)
                {
                    throw new InvalidOperationException();
                }

                var result =
                    EvaluationStatementTranspilerBase.ProcessEvaluation(context, scope, varDefStt.DefaultValue);

                if (!(result is ConstantValueStatement constantValueStatement))
                {
                    throw new InvalidOperationException(ErrorMessages.ConstantValueRequired);
                }

                if (!StatementHelpers.IsAssignableFrom(context, scope, varDefStt.TypeDescriptor,
                                                       constantValueStatement.TypeDescriptor))
                {
                    throw new TypeMismatchCompilerException(constantValueStatement.TypeDescriptor,
                                                            varDefStt.TypeDescriptor, varDefStt.Info);
                }

                scope.ReserveNewConstant(varDefStt.TypeDescriptor, varDefStt.Name, constantValueStatement.Value);
            }
            else
            {
                var skipDefinition = false;
                if (varDefStt.HasDefaultValue)
                {
                    var def        = varDefStt.DefaultValue;
                    var transpiler = context.GetEvaluationTranspilerForStatement(def);
                    if (transpiler == null)
                    {
                        throw new InvalidOperationException();
                    }

                    //it pins non-inlinable values to a helper variable:
                    //int x = 34 * myFunc();
                    //becomes:
                    //myFuncResult=myFunc()
                    //x=$((34 * myFuncResult))
                    if (varDefStt.TypeDescriptor.IsArray())
                    {
                        var p = new ExpressionBuilderParams(context, scope, metaWriter, writer,
                                                            new BlockStatement(null, varDefStt.Info));

                        scope.ReserveNewVariable(varDefStt.TypeDescriptor, varDefStt.Name);
                        skipDefinition = true;

                        var targetVar = new VariableAccessStatement(varDefStt.Name, varDefStt.Info);

                        var call = transpiler.CallApiFunction <ApiArray.Copy>(p, new[] { targetVar, def }, varDefStt,
                                                                              varDefStt.Info);

                        if (!call.IsEmptyResult)
                        {
                            WriteVariableDefinition(context, scope, writer, varDefStt.Name, call.Expression);
                        }
                    }
                    else
                    {
                        var result = transpiler.GetExpression(context, scope, metaWriter, writer, null, def);

                        WriteVariableDefinition(context, scope, writer, varDefStt.Name, result.Expression);
                    }
                }
                else
                {
                    WriteVariableDefinition(context, scope, writer, varDefStt.Name,
                                            context.Platform.GetDefaultValue(varDefStt.TypeDescriptor.DataType));
                }

                if (!skipDefinition)
                {
                    scope.ReserveNewVariable(varDefStt.TypeDescriptor, varDefStt.Name);
                }

                scope.IncrementStatements();
            }
        }
        public static void WriteIf(Context context, Scope scope, TextWriter writer, TextWriter nonInlinePartWriter,
                                   TextWriter metaWriter, IfElseStatement ifElseStatement)
        {
            var ifEscaped = false;
            var skipElse  = false;

            var condition =
                EvaluationStatementTranspilerBase.ProcessEvaluation(context, scope, ifElseStatement.MainIf.Condition);

            if (StatementHelpers.IsAbsoluteBooleanValue(condition, out var isTrue))
            {
                if (isTrue)
                {
                    BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter,
                                                                     ifElseStatement.MainIf.Statement, ScopeType.Block, true);

                    return;
                }

                ifEscaped = true;
            }
            else
            {
                writer.Write("if ");
                WriteCondition(context, scope, writer, metaWriter, nonInlinePartWriter, ifElseStatement, condition);
                writer.WriteLine();
                writer.WriteLine("then");
                BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter,
                                                                 ifElseStatement.MainIf.Statement, ScopeType.IfMainBlock, true);
            }

            if (ifElseStatement.ElseIfs != null)
            {
                foreach (var elseIf in ifElseStatement.ElseIfs)
                {
                    condition = EvaluationStatementTranspilerBase.ProcessEvaluation(context, scope, elseIf.Condition);

                    if (StatementHelpers.IsAbsoluteBooleanValue(condition, out isTrue))
                    {
                        if (isTrue)
                        {
                            if (!ifEscaped)
                            {
                                writer.WriteLine("else");
                            }

                            BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter,
                                                                             elseIf.Statement, ScopeType.IfElseBlock, true);

                            skipElse = true;
                            break;
                        }
                    }
                    else
                    {
                        if (ifEscaped)
                        {
                            writer.Write("if ");
                            ifEscaped = false;
                        }
                        else
                        {
                            writer.Write("elif ");
                        }

                        WriteCondition(context, scope, writer, metaWriter, nonInlinePartWriter, ifElseStatement,
                                       condition);
                        writer.WriteLine();
                        writer.WriteLine("then");
                        BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter,
                                                                         elseIf.Statement, ScopeType.IfIfElseBlock, true);
                    }
                }
            }

            if (!skipElse && ifElseStatement.Else != null)
            {
                if (ifEscaped)
                {
                    BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter,
                                                                     ifElseStatement.Else, ScopeType.IfMainBlock, true);
                }
                else
                {
                    writer.WriteLine("else");
                    BashBlockStatementTranspiler.WriteBlockStatement(context, scope, writer, metaWriter,
                                                                     ifElseStatement.Else, ScopeType.IfElseBlock, true);
                }
            }

            if (!ifEscaped)
            {
                writer.WriteLine("fi");

                scope.IncrementStatements();
            }
        }