private void UpdateVariableType(EV3Type type) { if ((int)type > (int)Type) { Type = type; } }
public ExpressionCompiler(T expression, EV3CompilerContext context) { ParentExpression = expression; Context = context; type = EV3Type.Unknown; value = null; }
protected void EnsureType() { if (type == EV3Type.Unknown) { type = CalculateType(); } }
public IEV3Variable CreateVariable(EV3Type type) { TempEV3Variable tempEV3Variable = new TempEV3Variable(type, () => tempIdGenerator(type)); createdTemps.Add(tempEV3Variable); return(tempEV3Variable); }
public static EV3Type ConvertToArray(this EV3Type type) { if (!type.IsArray()) { return((EV3Type)((int)type + ARRAY_OFFSET)); } else { return(type); } }
public static EV3Type BaseType(this EV3Type type) { if (type.IsArray()) { return((EV3Type)((int)type - ARRAY_OFFSET)); } else { return(type); } }
protected override string CalculateValue() { if (LeftCompiler.IsLiteral && RightCompiler.IsLiteral) { EV3Type commonType = CalculateCommonType(LeftCompiler.Type, RightCompiler.Type); if (commonType.IsArray() || commonType == EV3Type.Unknown) { return(null); } if (commonType.IsNumber()) { float leftValue = SmallBasicExtensions.ParseFloat(LeftCompiler.Value); float rightValue = SmallBasicExtensions.ParseFloat(RightCompiler.Value); switch (ParentExpression.Operator.Token) { case Token.Addition: return(SmallBasicExtensions.FormatFloat(leftValue + rightValue)); case Token.Subtraction: return(SmallBasicExtensions.FormatFloat(leftValue - rightValue)); case Token.Division: return(SmallBasicExtensions.FormatFloat(leftValue / rightValue)); case Token.Multiplication: return(SmallBasicExtensions.FormatFloat(leftValue * rightValue)); } } else { if (ParentExpression.Operator.Token == Token.Addition) { string leftValue = LeftCompiler.Value.Trim('\''); if (LeftCompiler.Type.IsNumber()) { leftValue = SmallBasicExtensions.FormatFloat(leftValue); } string rightValue = RightCompiler.Value.Trim('\''); if (RightCompiler.Type.IsNumber()) { rightValue = SmallBasicExtensions.FormatFloat(rightValue); } return('\'' + leftValue + rightValue + '\''); } } } return(null); }
protected EV3Type NormalizeType(EV3Type pt) { switch (pt) { case EV3Type.Int8: case EV3Type.Int16: case EV3Type.Int32: return(EV3Type.Float); case EV3Type.Int8Array: case EV3Type.Int16Array: case EV3Type.Int32Array: return(EV3Type.FloatArray); } return(pt); }
private int GetTempVariableId(EV3Type type) { int firstAvailable = -1; for (int i = 0; i <= MAX_TEMP_VARIABLE_INDEX; i++) { if (!tempVariablesCurrent[type].Contains(i)) { firstAvailable = i; break; } } tempVariablesCurrent[type].Add(firstAvailable); tempVariablesMax[type] = Math.Max(tempVariablesMax[type], firstAvailable); return(firstAvailable); }
protected EV3Type CalculateCommonType(EV3Type type1, EV3Type type2) { if (type1.BaseType() == type2.BaseType()) { if (type1.IsArray()) { return(type1); } return(type2); } if (type1.BaseType().IsNumber() && type2.BaseType().IsNumber()) { return(EV3Type.Float); } if ((type1.BaseType().IsNumber() && type2.BaseType() == EV3Type.String) || (type1.BaseType() == EV3Type.String && type2.BaseType().IsNumber())) { return(EV3Type.String); } return(EV3Type.Unknown); }
public override string Compile(TextWriter writer, IEV3Variable variable) { if (IsLiteral) { return(Value); } EV3Type commonType = CalculateCommonType(LeftCompiler.Type, RightCompiler.Type); if (commonType == EV3Type.Unknown) { AddError("Types of left and right side of expression don't match"); } else { using (var tempVariables = Context.UseTempVariables()) { string leftValue = CompileWithConvert(writer, LeftCompiler, commonType, tempVariables); string rightValue = CompileWithConvert(writer, RightCompiler, commonType, tempVariables); if (variable.Type.IsArray()) { variable = tempVariables.CreateVariable(variable.Type.BaseType()); } if (Type.IsNumber()) { switch (ParentExpression.Operator.Token) { case Token.Addition: writer.WriteLine($" ADDF {leftValue} {rightValue} {variable.Ev3Name}"); break; case Token.Subtraction: writer.WriteLine($" SUBF {leftValue} {rightValue} {variable.Ev3Name}"); break; case Token.Division: if (Context.DoDivisionCheck) { var sub = Context.FindMethod("Math.DivCheck"); if (variable.Type.IsArray() && !sub.ReturnType.IsArray()) { variable = tempVariables.CreateVariable(variable.Type.BaseType()); } sub.Compile(writer, Context, new string[] { leftValue, rightValue }, variable.Ev3Name); } else { writer.WriteLine($" DIVF {leftValue} {rightValue} {variable.Ev3Name}"); } break; case Token.Multiplication: writer.WriteLine($" MULF {leftValue} {rightValue} {variable.Ev3Name}"); break; } } else if (ParentExpression.Operator.Token == Token.Addition) { writer.WriteLine($" CALL TEXT.APPEND {leftValue} {rightValue} {variable.Ev3Name}"); } return(variable.Ev3Name); } } return(""); }
public static bool IsArrayOf(this EV3Type type, EV3Type baseType) { return(type.IsArray() && type.BaseType() == baseType); }
public static bool IsNumber(this EV3Type type) { int typeId = (int)type; return((int)EV3Type.Int8 <= typeId && typeId <= (int)EV3Type.Float); }
public static bool IsArray(this EV3Type type) { return((int)type >= (int)EV3Type.Int8Array); }
protected string CompileWithConvert(TextWriter writer, IExpressionCompiler compiler, EV3Type resultType, EV3Variables.TempVariableCreator tempVariables) { string value = compiler.Compile(writer, tempVariables.CreateVariable(compiler.Type)); if (compiler.Type.BaseType().IsNumber() && resultType.BaseType() == EV3Type.String) { if (compiler.IsLiteral) { return("'" + SmallBasicExtensions.FormatFloat(value) + "'"); } else { IEV3Variable outputVariable = tempVariables.CreateVariable(EV3Type.String); writer.WriteLine($" STRINGS VALUE_FORMATTED {value} '%g' 99 {outputVariable.Ev3Name}"); return(outputVariable.Ev3Name); } } else { return(value); } }
public TempEV3Variable(EV3Type type, Func <int> tempIdGenerator) { Type = type; this.tempIdGenerator = tempIdGenerator; }