Modified the nodes of the AST to use 0/1 for bools internally. So all of the Relation...
authorMichael Welch <michaelgwelch@gmail.com>
Fri, 29 Dec 2006 02:03:36 +0000 (02:03 +0000)
committerMichael Welch <michaelgwelch@gmail.com>
Fri, 29 Dec 2006 02:03:36 +0000 (02:03 +0000)
This requires that any time a bool is used in a place that a number is required a conversion to double is required. Likewise, if a double is on the stack and we need a .NET bool a conversion is required. So almost every Node needed to be modified.

19 files changed:
mbasic/SyntaxTree/Add.cs
mbasic/SyntaxTree/Assign.cs
mbasic/SyntaxTree/BasicType.cs
mbasic/SyntaxTree/BinaryOperator.cs [new file with mode: 0644]
mbasic/SyntaxTree/Division.cs
mbasic/SyntaxTree/Expression.cs
mbasic/SyntaxTree/For.cs
mbasic/SyntaxTree/Function.cs
mbasic/SyntaxTree/If.cs
mbasic/SyntaxTree/Multiply.cs
mbasic/SyntaxTree/Negative.cs
mbasic/SyntaxTree/Node.cs
mbasic/SyntaxTree/Power.cs
mbasic/SyntaxTree/Print.cs
mbasic/SyntaxTree/RelationalExpression.cs
mbasic/SyntaxTree/Subtract.cs
mbasic/SyntaxTree/Tab.cs
mbasic/mbasic.csproj
samples/ForStatementTest.mbas

index 8e11f34..b94a4d6 100644 (file)
@@ -26,39 +26,17 @@ using System.Reflection.Emit;
 
 namespace mbasic.SyntaxTree
 {
-    class Add : Expression
+    class Add : BinaryOperator
     {
-        Expression op1;
-        Expression op2;
-        BasicType type;
         public Add(Expression e1, Expression e2, LineId line)
-            : base(line)
+            : base(e1, e2, line)
         {
-            this.op1 = e1;
-            this.op2 = e2;
         }
 
-        public override void Emit(ILGenerator gen)
+        protected override void EmitOperation(ILGenerator gen)
         {
-            op1.Emit(gen);
-            op2.Emit(gen);
             gen.Emit(OpCodes.Add);
         }
 
-
-
-        public override BasicType GetBasicType()
-        {
-            BasicType type1 = op1.GetBasicType();
-            BasicType type2 = op2.GetBasicType();
-            if (type1 == BasicType.Number && type2 == BasicType.Number)
-            {
-                type = BasicType.Number;
-            }
-            else
-                TypeMismtach();
-            return type;
-
-        }
     }
 }
index 09f307d..697fdae 100644 (file)
@@ -28,6 +28,7 @@ namespace mbasic.SyntaxTree
     {
         int localIndex;
         Expression value;
+        BasicType valueType;
         public Assign(int index, Expression value, LineId line)
             : base(line)
         {
@@ -44,6 +45,7 @@ namespace mbasic.SyntaxTree
             if (!labelSetAlready) MarkLabel(gen);
             MarkSequencePoint(gen);
             value.Emit(gen);
+            if (valueType == BasicType.Boolean) EmitConvertToDouble(gen);
             gen.Emit(OpCodes.Stloc, locals[localIndex]);
         }
 
@@ -54,7 +56,12 @@ namespace mbasic.SyntaxTree
             if (varType == typeof(string)) varBasicType = BasicType.String;
             else varBasicType = BasicType.Number;
 
-            if (varBasicType == value.GetBasicType()) return;
+            valueType = value.GetBasicType();
+
+            if (varBasicType == BasicType.String && valueType == BasicType.String) return;
+
+            if (valueType == BasicType.Number || valueType == BasicType.Boolean) return;
+
             throw new Exception("Type mismatch exception in an assignment");
             
         }
index b9da4cb..f9bcfd6 100644 (file)
@@ -25,6 +25,7 @@ namespace mbasic.SyntaxTree
     {
         Number,
         String,
+        Boolean,    // Not really a TiBasic type, but one used for optimization. A user will never "see" one of these.
         Error
     }
 }
\ No newline at end of file
diff --git a/mbasic/SyntaxTree/BinaryOperator.cs b/mbasic/SyntaxTree/BinaryOperator.cs
new file mode 100644 (file)
index 0000000..18e19b3
--- /dev/null
@@ -0,0 +1,52 @@
+using System;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using System.Reflection.Emit;\r
+\r
+namespace mbasic.SyntaxTree\r
+{\r
+    abstract class BinaryOperator : Expression\r
+    {\r
+        Expression expr1;\r
+        Expression expr2;\r
+        BasicType expr1Type;\r
+        BasicType expr2Type;\r
+        BasicType ourType;\r
+\r
+        protected BinaryOperator(Expression e1, Expression e2, LineId line)\r
+            : base(line)\r
+        {\r
+            this.expr1 = e1;\r
+            this.expr2 = e2;\r
+        }\r
+\r
+        public override void Emit(ILGenerator gen)\r
+        {\r
+            expr1.Emit(gen);\r
+            if (expr1Type == BasicType.Boolean) EmitConvertToDouble(gen);\r
+            expr2.Emit(gen);\r
+            if (expr2Type == BasicType.Boolean) EmitConvertToDouble(gen);\r
+            EmitOperation(gen);\r
+        }\r
+\r
+\r
+\r
+        public override BasicType GetBasicType()\r
+        {\r
+            expr1Type = expr1.GetBasicType();\r
+            expr2Type = expr2.GetBasicType();\r
+            if ((expr1Type == BasicType.Boolean || expr1Type == BasicType.Number)\r
+                && (expr2Type == BasicType.Boolean || expr2Type == BasicType.Number))\r
+            {\r
+                ourType = BasicType.Number;\r
+            }\r
+            else\r
+            {\r
+                ourType = BasicType.Error;\r
+            }\r
+            return ourType;\r
+        }\r
+        protected abstract void EmitOperation(ILGenerator gen);\r
+\r
+    }\r
+}\r
index ee02a59..83d45f5 100644 (file)
@@ -25,37 +25,18 @@ using System.Reflection.Emit;
 
 namespace mbasic.SyntaxTree
 {
-    class Division : Expression
+    class Division : BinaryOperator
     {
-        Expression op1;
-        Expression op2;
-        BasicType type;
+
 
         public Division(Expression e1, Expression e2, LineId line)
-            : base(line)
+            : base(e1, e2, line)
         {
-            this.op1 = e1;
-            this.op2 = e2;
         }
 
-        public override BasicType GetBasicType()
-        {
-
-            BasicType type1 = op1.GetBasicType();
-            BasicType type2 = op2.GetBasicType();
-            if (type1 == BasicType.Number && type2 == BasicType.Number)
-            {
-                type = BasicType.Number;
-            }
-            else
-                TypeMismtach();
-            return type;
-        }
 
-        public override void Emit(ILGenerator gen)
+        protected override void EmitOperation(ILGenerator gen)
         {
-            op1.Emit(gen);
-            op2.Emit(gen);
             gen.Emit(OpCodes.Div);
         }
     }
index 69e2231..340c862 100644 (file)
@@ -36,5 +36,12 @@ namespace mbasic.SyntaxTree
             string msg = String.Format("Type Mismatch On {0}", line.Label);
             throw new Exception(msg);
         }
+
+        protected static bool TypeIsNotNumeric(BasicType type)
+        {
+            if (type != BasicType.Number && type != BasicType.Boolean) return true;
+            return false;
+        }
+
     }
 }
index ded8625..72959de 100644 (file)
@@ -48,7 +48,7 @@ namespace mbasic.SyntaxTree
         public override void CheckTypes()
         {
             init.CheckTypes();
-            if (comparison.GetBasicType() != BasicType.Number) throw new Exception("Type mismatch in comparison of for loop");
+            if (comparison.GetBasicType() != BasicType.Boolean) throw new Exception("Type mismatch in comparison of for loop");
             update.CheckTypes();
             stmt.CheckTypes();
         }
@@ -81,9 +81,7 @@ namespace mbasic.SyntaxTree
 
             gen.MarkLabel(condition);
             comparison.Emit(gen);
-            gen.Emit(OpCodes.Ldc_R8, 0.0);
-            gen.Emit(OpCodes.Ceq);
-            gen.Emit(OpCodes.Brfalse, start);
+            gen.Emit(OpCodes.Brtrue, start);
 
         }
 
index fd7673b..faff1b0 100644 (file)
@@ -96,58 +96,58 @@ namespace mbasic.SyntaxTree
                     EmitFunctionCall(gen, rndMethod);
                     break;
                 case "INT":
-                    EmitFunctionCall(gen, intMethod, exprs[0]);
+                    EmitFunctionCall(gen, intMethod);
                     break;
                 case "ASC":
-                    EmitFunctionCall(gen, ascMethod, line.Label, exprs[0]);
+                    EmitFunctionCall(gen, ascMethod, line.Label);
                     break;
                 case "CHR$":
-                    EmitFunctionCall(gen, chrMethod, line.Label, exprs[0]);
+                    EmitFunctionCall(gen, chrMethod, line.Label);
                     break;
                 case "LEN":
-                    EmitFunctionCall(gen, lenMethod, exprs[0]);
+                    EmitFunctionCall(gen, lenMethod);
                     break;
                 case "POS":
-                    EmitFunctionCall(gen, posMethod, line.Label, exprs[0], exprs[1], exprs[2]);
+                    EmitFunctionCall(gen, posMethod, line.Label);
                     break;
                 case "SEG$":
-                    EmitFunctionCall(gen, segMethod, line.Label, exprs[0], exprs[1], exprs[2]);
+                    EmitFunctionCall(gen, segMethod, line.Label);
                     break;
                 case "STR$":
-                    EmitFunctionCall(gen, strMethod, exprs[0]);
+                    EmitFunctionCall(gen, strMethod);
                     break;
                 case "VAL":
-                    EmitFunctionCall(gen, valMethod, line.Label, exprs[0]);
+                    EmitFunctionCall(gen, valMethod, line.Label);
                     break;
 
                     // Numeric Functions
                 case "ABS":
-                    EmitFunctionCall(gen, absMethod, exprs[0]);
+                    EmitFunctionCall(gen, absMethod);
                     break;
                 case "ATN":
-                    EmitFunctionCall(gen, atnMethod, exprs[0]);
+                    EmitFunctionCall(gen, atnMethod);
                     break;
                 case "COS":
-                    EmitFunctionCall(gen, cosMethod, exprs[0]);
+                    EmitFunctionCall(gen, cosMethod);
                     break;
                 case "EXP":
-                    EmitFunctionCall(gen, expMethod, exprs[0]);
+                    EmitFunctionCall(gen, expMethod);
                     break;
                 case "LOG":
-                    EmitFunctionCall(gen, logMethod, line.Label, exprs[0]);
+                    EmitFunctionCall(gen, logMethod, line.Label);
                     break;
                 case "SGN":
-                    EmitFunctionCall(gen, sgnMethod, exprs[0]);
+                    EmitFunctionCall(gen, sgnMethod);
                     gen.Emit(OpCodes.Conv_R8); // Sign returns an int
                     break;
                 case "SIN":
-                    EmitFunctionCall(gen, sinMethod, exprs[0]);
+                    EmitFunctionCall(gen, sinMethod);
                     break;
                 case "SQR":
-                    EmitFunctionCall(gen, sqrMethod, line.Label, exprs[0]);
+                    EmitFunctionCall(gen, sqrMethod, line.Label);
                     break;
                 case "TAN":
-                    EmitFunctionCall(gen, tanMethod, exprs[0]);
+                    EmitFunctionCall(gen, tanMethod);
                     break;
 
             }
@@ -169,7 +169,7 @@ namespace mbasic.SyntaxTree
                     return BasicType.Number;
                 case "CHR$":
                     if (exprs.Length != 1) return BasicType.Error;
-                    if (argsTypes[0] != BasicType.Number) return BasicType.Error;
+                    if (TypeIsNotNumeric(argsTypes[0])) return BasicType.Error;
                     return BasicType.String;
                 case "LEN":
                     if (exprs.Length != 1) return BasicType.Error;
@@ -179,17 +179,17 @@ namespace mbasic.SyntaxTree
                     if (exprs.Length != 3) return BasicType.Error;
                     if (argsTypes[0] != BasicType.String) return BasicType.Error;
                     if (argsTypes[1] != BasicType.String) return BasicType.Error;
-                    if (argsTypes[2] != BasicType.Number) return BasicType.Error;
+                    if (TypeIsNotNumeric(argsTypes[2])) return BasicType.Error;
                     return BasicType.Number;
                 case "SEG$":
                     if (exprs.Length != 3) return BasicType.Error;
                     if (argsTypes[0] != BasicType.String) return BasicType.Error;
-                    if (argsTypes[1] != BasicType.Number) return BasicType.Error;
-                    if (argsTypes[2] != BasicType.Number) return BasicType.Error;
+                    if (TypeIsNotNumeric(argsTypes[1])) return BasicType.Error;
+                    if (TypeIsNotNumeric(argsTypes[2])) return BasicType.Error;
                     return BasicType.String;
                 case "STR$":
                     if (exprs.Length != 1) return BasicType.Error;
-                    if (argsTypes[0] != BasicType.Number) return BasicType.Error;
+                    if (TypeIsNotNumeric(argsTypes[0])) return BasicType.Error;
                     return BasicType.String;
                 case "VAL":
                     if (exprs.Length != 1) return BasicType.Error;
@@ -208,7 +208,7 @@ namespace mbasic.SyntaxTree
                 case "SQR":
                 case "TAN":
                     if (exprs.Length != 1) return BasicType.Error;
-                    if (argsTypes[0] != BasicType.Number) return BasicType.Error;
+                    if (TypeIsNotNumeric(argsTypes[0])) return BasicType.Error;
                     return BasicType.Number;
                 default:
                     return BasicType.Error;
@@ -216,19 +216,22 @@ namespace mbasic.SyntaxTree
         }
 
         private void EmitFunctionCall(ILGenerator gen,
-            MethodInfo method, params Expression[] exprs)
+            MethodInfo method)
         {
-            foreach (Expression expr in exprs)
-                expr.Emit(gen);
+            for (int i = 0; i < exprs.Length; i++)
+            {
+                exprs[i].Emit(gen);
+                if (argsTypes[i] == BasicType.Boolean) EmitConvertToDouble(gen);
+            }
 
             gen.Emit(OpCodes.Call, method);
         }
 
         private void EmitFunctionCall(ILGenerator gen,
-            MethodInfo method, string label, params Expression[] exprs)
+            MethodInfo method, string label)
         {
             gen.Emit(OpCodes.Ldstr, label);
-            EmitFunctionCall(gen, method, exprs);
+            EmitFunctionCall(gen, method);
         }
 
 
index 4e5d9ae..1da618a 100644 (file)
@@ -30,6 +30,7 @@ namespace mbasic.SyntaxTree
         Goto jmp;
         Goto elseJmp;
         Expression conditional;
+        BasicType exprType;
         public If(Expression conditional, string label, LineId line) : base(line)
         {
             jmp = new Goto(label, line);
@@ -47,7 +48,11 @@ namespace mbasic.SyntaxTree
 
         public override void CheckTypes()
         {
-            if (conditional.GetBasicType() == BasicType.Number) return;
+            exprType = conditional.GetBasicType();
+            
+            if (conditional.GetBasicType() == BasicType.Number || 
+                conditional.GetBasicType() == BasicType.Boolean) return;
+            throw new Exception(String.Format("Type error in conditional of If on {0}", line.Label));
         }
 
         public override void Emit(ILGenerator gen)
@@ -61,8 +66,8 @@ namespace mbasic.SyntaxTree
             MarkSequencePoint(gen);
             Label falseCase = gen.DefineLabel();
             conditional.Emit(gen);
-            gen.Emit(OpCodes.Ldc_R8, 0.0);
-            gen.Emit(OpCodes.Beq_S, falseCase);
+            if (exprType == BasicType.Number) EmitConvertToBoolean(gen);
+            gen.Emit(OpCodes.Brfalse_S, falseCase);
             jmp.Emit(gen, true);
             gen.MarkLabel(falseCase);
             if (elseJmp != null) elseJmp.Emit(gen, true);
index af38b87..9809e99 100644 (file)
@@ -26,37 +26,15 @@ using System.Reflection.Emit;
 
 namespace mbasic.SyntaxTree
 {
-    class Multiply : Expression
+    class Multiply : BinaryOperator
     {
-        Expression op1;
-        Expression op2;
-        BasicType type;
-
         public Multiply(Expression e1, Expression e2, LineId line)
-            : base(line)
+            : base(e1, e2, line)
         {
-            this.op1 = e1;
-            this.op2 = e2;
-        }
-
-        public override BasicType GetBasicType()
-        {
-
-            BasicType type1 = op1.GetBasicType();
-            BasicType type2 = op2.GetBasicType();
-            if (type1 == BasicType.Number && type2 == BasicType.Number)
-            {
-                type = BasicType.Number;
-            }
-            else
-                TypeMismtach();
-            return type;
         }
 
-        public override void Emit(ILGenerator gen)
+        protected override void EmitOperation(ILGenerator gen)
         {
-            op1.Emit(gen);
-            op2.Emit(gen);
             gen.Emit(OpCodes.Mul);
         }
     }
index b013502..df86dff 100644 (file)
@@ -29,6 +29,7 @@ namespace mbasic.SyntaxTree
     class Negative : Expression
     {
         Expression value;
+        BasicType valueType;
         BasicType type;
         public Negative(Expression value, LineId line) : base(line)
         {
@@ -36,14 +37,17 @@ namespace mbasic.SyntaxTree
         }
         public override BasicType GetBasicType()
         {
-            if (value.GetBasicType() == BasicType.Number)
+            valueType = value.GetBasicType();
+            if (valueType == BasicType.Number || valueType == BasicType.Boolean)
                 type = BasicType.Number;
+            else type = BasicType.Error;
             return type;
         }
 
         public override void Emit(System.Reflection.Emit.ILGenerator gen)
         {
             value.Emit(gen);
+            if (valueType == BasicType.Boolean) EmitConvertToDouble(gen);
             gen.Emit(OpCodes.Neg);
         }
     }
index 7291dd0..8a7040c 100644 (file)
@@ -46,5 +46,26 @@ using System.Reflection;
         public static bool debug;
         public static ISymbolDocumentWriter writer;
 
+        /// <summary>
+        /// converts a boolean to a double
+        /// </summary>
+        /// <param name="gen"></param>
+        protected static void EmitConvertToDouble(ILGenerator gen)
+        {
+            gen.Emit(OpCodes.Conv_R8);
+            gen.Emit(OpCodes.Neg);
+        }
+
+
+        private static readonly MethodInfo convertToBooleanMethod =
+            typeof(Convert).GetMethod("ToBoolean", new Type[] { typeof(double) });
+        /// <summary>
+        /// converts a double to a boolean
+        /// </summary>
+        /// <param name="gen"></param>
+        protected static void EmitConvertToBoolean(ILGenerator gen)
+        {
+            gen.Emit(OpCodes.Call, convertToBooleanMethod);
+        }
     }
 }
index 42b087a..8d3a41b 100644 (file)
@@ -26,42 +26,18 @@ using System.Reflection.Emit;
 using System.Reflection;
 namespace mbasic.SyntaxTree
 {
-    class Power : Expression
+    class Power : BinaryOperator
     {
         private static readonly MethodInfo powerMethod =
             typeof(Math).GetMethod("Pow");
-        Expression op1;
-        Expression op2;
-        BasicType type;
         public Power(Expression e1, Expression e2, LineId line)
-            : base(line)
+            : base(e1, e2, line)
         {
-            this.op1 = e1;
-            this.op2 = e2;
         }
 
-        public override void Emit(ILGenerator gen)
+        protected override void EmitOperation(ILGenerator gen)
         {
-            
-            op1.Emit(gen);
-            op2.Emit(gen);
             gen.Emit(OpCodes.Call, powerMethod);
         }
-
-
-
-        public override BasicType GetBasicType()
-        {
-            BasicType type1 = op1.GetBasicType();
-            BasicType type2 = op2.GetBasicType();
-            if (type1 == BasicType.Number && type2 == BasicType.Number)
-            {
-                type = BasicType.Number;
-            }
-            else
-                TypeMismtach();
-            return type;
-
-        }
     }
 }
index 3b64a05..41b1d03 100644 (file)
@@ -61,6 +61,11 @@ namespace mbasic.SyntaxTree
                 gen.Emit(OpCodes.Dup); // Duplicate the array reference, so it's still on stack after this use
                 gen.Emit(OpCodes.Ldc_I4, i);
                 values[i].Emit(gen);
+                if (printItemTypes[i] == BasicType.Boolean)
+                {
+                    EmitConvertToDouble(gen);
+                    gen.Emit(OpCodes.Box, typeof(double));
+                }
                 if (printItemTypes[i] == BasicType.Number) gen.Emit(OpCodes.Box, typeof(double));
                 gen.Emit(OpCodes.Stelem_Ref);
             }
index a8c53ff..7bd55a7 100644 (file)
@@ -53,7 +53,7 @@ namespace mbasic.SyntaxTree
             if (t1 == t2)
             {
                 argType = t1;
-                return BasicType.Number;
+                return BasicType.Boolean;
             }
             return BasicType.Error;
         }
@@ -66,12 +66,6 @@ namespace mbasic.SyntaxTree
             EmitOperation(gen);
 
             if (not) EmitNot(gen);
-
-            // TI Basic uses -1/0, .NET uses 1/0, 
-            // plus we need to convert from Int32 to double
-            gen.Emit(OpCodes.Conv_R8);
-            gen.Emit(OpCodes.Neg);
-
         }
 
         private void EmitNot(ILGenerator gen)
index df5cd1d..92ae6dc 100644 (file)
@@ -25,37 +25,17 @@ using System.Reflection.Emit;
 
 namespace mbasic.SyntaxTree
 {
-    class Subtract : Expression
+    class Subtract : BinaryOperator
     {
-        Expression op1;
-        Expression op2;
-        BasicType type;
 
-        public Subtract(Expression e1, Expression e2, LineId line)
-            : base(line)
-        {
-            this.op1 = e1;
-            this.op2 = e2;
-        }
 
-        public override BasicType GetBasicType()
+        public Subtract(Expression e1, Expression e2, LineId line)
+            : base(e1, e2, line)
         {
-
-            BasicType type1 = op1.GetBasicType();
-            BasicType type2 = op2.GetBasicType();
-            if (type1 == BasicType.Number && type2 == BasicType.Number)
-            {
-                type = BasicType.Number;
-            }
-            else
-                TypeMismtach();
-            return type;
         }
 
-        public override void Emit(ILGenerator gen)
+        protected override void EmitOperation(ILGenerator gen)
         {
-            op1.Emit(gen);
-            op2.Emit(gen);
             gen.Emit(OpCodes.Sub);
         }
     }
index 6d5cae4..1ae7dbf 100644 (file)
@@ -30,6 +30,7 @@ namespace mbasic.SyntaxTree
     class Tab : Expression
     {
         Expression expr;
+        BasicType exprType;
         public Tab(Expression expr, LineId line)
             : base(line)
         {
@@ -37,7 +38,8 @@ namespace mbasic.SyntaxTree
         }
         public override BasicType GetBasicType()
         {
-            if (expr.GetBasicType() == BasicType.Number) return BasicType.String;
+            exprType = expr.GetBasicType();
+            if (exprType == BasicType.Number || exprType == BasicType.Boolean) return BasicType.String;
             return BasicType.Error;
         }
 
@@ -49,7 +51,8 @@ namespace mbasic.SyntaxTree
         public override void Emit(ILGenerator gen)
         {
             gen.Emit(OpCodes.Ldstr, "\t");
-            expr.Emit(gen); // will load a double on the stack
+            expr.Emit(gen); // will load a double (or boolean) on the stack
+            if (exprType == BasicType.Boolean) EmitConvertToDouble(gen);
             gen.Emit(OpCodes.Call, toStringMethod); // will convert number to string
             gen.Emit(OpCodes.Call, concatenateMethod); // will concatenate them into one string
         }
index b99472a..c1175df 100644 (file)
@@ -42,6 +42,7 @@
     <Compile Include="SyntaxTree\Add.cs" />\r
     <Compile Include="SyntaxTree\Assign.cs" />\r
     <Compile Include="SyntaxTree\BasicType.cs" />\r
+    <Compile Include="SyntaxTree\BinaryOperator.cs" />\r
     <Compile Include="SyntaxTree\Block.cs" />\r
     <Compile Include="SyntaxTree\Concatenate.cs" />\r
     <Compile Include="SyntaxTree\Data.cs" />\r
index 7713752..884e06e 100644 (file)
@@ -4,4 +4,4 @@
 120 print i
 130 Next i
 140 x = x - 1
-150 if x >= 0 then 100
+150 if (x >= 0) * 6 then 100