public IncludeStatement(EvaluationStatement target, StatementInfo info) { Target = target; Info = info; TraversableChildren = StatementHelpers.CreateChildren(target); }
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)); } } }
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); }
public IndexerAccessStatement(EvaluationStatement source, EvaluationStatement indexer, StatementInfo info) { Source = source; Indexer = indexer; Info = info; TraversableChildren = StatementHelpers.CreateChildren(source, indexer); }
public ForEachStatement(IStatement variable, EvaluationStatement iterator, IStatement statement, StatementInfo info) { Variable = variable; Iterator = iterator; Statement = statement; Info = info; TraversableChildren = StatementHelpers.CreateChildren(variable, iterator, statement); }
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); }
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); } }
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(); } }