public override PinnedVariableResult PinFloatingPointExpressionToVariable( ExpressionBuilderParams p, TypeDescriptor typeDescriptor, string nameHint, string expression, EvaluationStatement template) { var variableName = p.Scope.NewHelperVariable(typeDescriptor, nameHint); expression = $"`awk \"BEGIN {{print ({expression})}}\"`"; BashVariableDefinitionStatementTranspiler.WriteVariableDefinition( p.Context, p.Scope, p.NonInlinePartWriter, variableName, expression ); template = new VariableAccessStatement(variableName, template.Info); return(new PinnedVariableResult( typeDescriptor, variableName, FormatVariableAccessExpression(p, typeDescriptor, variableName, template ), template)); }
public override PinnedVariableResult PinExpressionToVariable(ExpressionBuilderParams p, string nameHint, ExpressionResult result) { var variableName = p.Scope.NewHelperVariable(result.TypeDescriptor, nameHint); BashVariableDefinitionStatementTranspiler.WriteVariableDefinition( p.Context, p.Scope, p.NonInlinePartWriter, variableName, result.Expression ); var template = new VariableAccessStatement(variableName, result.Template.Info); return(new PinnedVariableResult( result.TypeDescriptor, variableName, FormatVariableAccessExpression(p, result.TypeDescriptor, variableName, template ), template)); }
public bool TryGetFunctionInfo(VariableAccessStatement variableAccessStatement, out FunctionInfo functionInfo) { var funcInfo = new FunctionInfo(variableAccessStatement.ClassName, variableAccessStatement.VariableName); var that = this; do { if (that._functions.TryGetValue(funcInfo, out functionInfo)) { return(true); } } while ((that = that.Parent) != null); return(false); }
// // public bool TryGetConstantInfo(string constantName, out ConstantInfo constantInfo) // { // var constInfo = new ConstantInfo(constantName); // // var that = this; // do // { // if (that._constants.TryGetValue(constInfo, out constantInfo)) // { // return true; // } // // } while ((that = that.Parent) != null); // // return false; // } public bool TryGetConstantInfo(VariableAccessStatement variableAccessStatement, out ConstantInfo constantInfo) { var constInfo = new ConstantInfo(variableAccessStatement.VariableName); var that = this; do { if (that._constants.TryGetValue(constInfo, out constantInfo)) { return(true); } } while ((that = that.Parent) != null); return(false); }
public bool TryGetVariableInfo(VariableAccessStatement variableAccessStatement, out VariableInfo variableInfo) { var varInfo = new VariableInfo(variableAccessStatement.ClassName, variableAccessStatement.VariableName); var that = this; do { if (that._variables.TryGetValue(varInfo, out variableInfo)) { return(true); } } while ((that = that.Parent) != null); return(false); }
public override void WriteBlock(Context context, Scope scope, TextWriter writer, TextWriter metaWriter, IStatement statement) { if (!(statement is ReturnStatement returnStatement)) { throw new InvalidOperationException(); } var returnResult = returnStatement.Result; if (returnResult != null) { var transpiler = context.GetEvaluationTranspilerForStatement(returnResult); var type = returnResult.GetDataType(context, scope); if (type.IsArray()) { var varName = context.GetLastFunctionCallStorageVariable(type, metaWriter); var leftSide = new VariableAccessStatement(varName, returnResult.Info); var stt = new AssignmentStatement(leftSide, returnResult, returnResult.Info, statement); transpiler.WriteInline(context, scope, writer, metaWriter, writer, returnResult); } else { var result = transpiler.GetExpression(context, scope, metaWriter, writer, null, returnResult); writer.Write("echo "); writer.Write(result.Expression); writer.WriteLine(); } } if (scope.StatementCount > 1 && scope.Type != ScopeType.MethodRoot) { writer.Write("return "); writer.Write(context.Flags.SuccessStatusCode); writer.WriteLine(); } scope.IncrementStatements(); }
public IdentifierNotFoundCompilerException(VariableAccessStatement variableAccessStatement) : base(CreateMessage(variableAccessStatement.VariableName, variableAccessStatement.Info), variableAccessStatement.Info) { }
protected override ExpressionResult CreateExpressionRecursive(ExpressionBuilderParams p, EvaluationStatement statement) { switch (statement) { case LogicalEvaluationStatement logicalEvaluationStatement: { if (p.UsageContext is IfElseStatement) { break; } switch (logicalEvaluationStatement.Operator) { case EqualOperator _: case NotEqualOperator _: { using (var writer = new StringWriter()) { var expressionBuilderParams = new ExpressionBuilderParams(p, writer); var leftResult = CreateExpressionRecursive(expressionBuilderParams, logicalEvaluationStatement.Left); var rightResult = CreateExpressionRecursive(expressionBuilderParams, logicalEvaluationStatement.Right); if (leftResult.TypeDescriptor.IsString() && rightResult.TypeDescriptor.IsString()) { HandleNotices(expressionBuilderParams, ref leftResult, ref rightResult); expressionBuilderParams.NonInlinePartWriter.WriteLine( $"[ {leftResult.Expression} {logicalEvaluationStatement.Operator} {rightResult.Expression} ]"); string varName; if (logicalEvaluationStatement.ParentStatement is AssignmentStatement || logicalEvaluationStatement.ParentStatement is VariableDefinitionStatement) { varName = UnixBashPlatform.LastStatusCodeStoreVariableName; } else { varName = BashVariableDefinitionStatementTranspiler .WriteLastStatusCodeStoreVariableDefinition(expressionBuilderParams.Context, expressionBuilderParams.Scope, expressionBuilderParams.NonInlinePartWriter, "cmp_strings"); } var template = new VariableAccessStatement( varName, logicalEvaluationStatement.Info ); p.NonInlinePartWriter.Write(writer); return(new ExpressionResult( TypeDescriptor.Boolean, $"${varName}", template, PinRequiredNotice )); } } break; } } break; } case ArithmeticEvaluationStatement arithmeticEvaluationStatement: { switch (arithmeticEvaluationStatement.Operator) { case AdditionOperator _: { using (var writer = new StringWriter()) { var expressionBuilderParams = new ExpressionBuilderParams(p, writer); var leftResult = CreateExpressionRecursive(expressionBuilderParams, arithmeticEvaluationStatement.Left); var rightResult = CreateExpressionRecursive(expressionBuilderParams, arithmeticEvaluationStatement.Right); if (leftResult.TypeDescriptor.IsString() || rightResult.TypeDescriptor.IsString()) { HandleNotices(expressionBuilderParams, ref leftResult, ref rightResult); var leftExp = leftResult.Expression; var rightExp = rightResult.Expression; if (leftResult.Template is VariableAccessStatement) { leftExp = FormatStringConcatenationVariableAccess(leftExp); } if (rightResult.Template is VariableAccessStatement) { rightExp = FormatStringConcatenationVariableAccess(rightExp); } if (!leftResult.TypeDescriptor.IsString() && !(leftResult.Template is VariableAccessStatement)) { leftExp = $"$(({leftExp}))"; } if (!rightResult.TypeDescriptor.IsString() && !(rightResult.Template is VariableAccessStatement)) { rightExp = $"$(({rightExp}))"; } var concatExp = $"{leftExp}{rightExp}"; var newTemp = new ArithmeticEvaluationStatement( leftResult.Template, arithmeticEvaluationStatement.Operator, rightResult.Template, arithmeticEvaluationStatement.Info ); leftResult.Template.ParentStatement = newTemp; rightResult.Template.ParentStatement = newTemp; p.NonInlinePartWriter.Write(writer); return(new ExpressionResult( TypeDescriptor.String, concatExp, newTemp )); } } break; } } break; } case ArrayStatement arrayStatement: { string sourceName; if (arrayStatement.ParentStatement is VariableDefinitionStatement variableDefinitionStatement) { sourceName = variableDefinitionStatement.Name; } else if (arrayStatement.ParentStatement is AssignmentStatement assignmentStatement) { if (!(assignmentStatement.LeftSide is VariableAccessStatement variableAccessStatement)) { throw new InvalidStatementStructureCompilerException(assignmentStatement, assignmentStatement.Info); } sourceName = variableAccessStatement.VariableName; } else if (arrayStatement.ParentStatement is ReturnStatement returnStatement) { sourceName = p.Context.GetLastFunctionCallStorageVariable(arrayStatement.Type, p.MetaWriter); } else { sourceName = p.Scope.NewHelperVariable(arrayStatement.Type, "array_helper"); } if (arrayStatement.Elements != null) { for (var i = 0; i < arrayStatement.Elements.Length; i++) { p.NonInlinePartWriter.Write($"{sourceName}[{i}]="); var element = CreateExpression(p, arrayStatement.Elements[i]); p.NonInlinePartWriter.WriteLine(element); } return(ExpressionResult.EmptyResult); } if (arrayStatement.Length != null) { var sourceNameEval = new VariableAccessStatement(sourceName, arrayStatement.Info); return(CallApiFunction <ApiArray.Initialize>(p, new[] { sourceNameEval, arrayStatement.Length }, arrayStatement.ParentStatement, arrayStatement.Info)); } throw new InvalidStatementStructureCompilerException(arrayStatement, arrayStatement.Info); } } return(base.CreateExpressionRecursive(p, statement)); }
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(); } }