merged the use of fields into trunk
authorMichael Welch <michaelgwelch@gmail.com>
Sun, 16 Sep 2007 20:27:41 +0000 (20:27 +0000)
committerMichael Welch <michaelgwelch@gmail.com>
Sun, 16 Sep 2007 20:27:41 +0000 (20:27 +0000)
20 files changed:
mbasic/ArrayElement.cs
mbasic/Location.cs
mbasic/Program.cs
mbasic/SyntaxTree/Assign.cs
mbasic/SyntaxTree/BuiltInsMethodCall.cs
mbasic/SyntaxTree/Function.cs
mbasic/SyntaxTree/Gosub.cs
mbasic/SyntaxTree/Input.cs
mbasic/SyntaxTree/Node.cs
mbasic/SyntaxTree/OnGoto.cs
mbasic/SyntaxTree/Print.cs
mbasic/SyntaxTree/Randomize.cs
mbasic/SyntaxTree/Read.cs
mbasic/SyntaxTree/Restore.cs
mbasic/SyntaxTree/Tab.cs
mbasic/SyntaxTree/VariableReference.cs
mbasic/Token.cs
mbasic/Variable.cs
mbasic/VariableLocation.cs
mbasic/mbasic.csproj

index af83feb..37a2ef2 100644 (file)
@@ -4,7 +4,7 @@ using System.Text;
 using System.Reflection.Emit;
 using mbasic.SyntaxTree;
 using System.Reflection;
-using TIBasicRuntime;
+using TiBasicRuntime;
 namespace mbasic
 {
     class ArrayElement : Location
@@ -64,9 +64,9 @@ namespace mbasic
 
 
         public override void EmitStore(ILGenerator gen, 
-            List<LocalBuilder> locals, Expression value)
+            IList<FieldBuilder> fields, Expression value)
         {
-            this.location.EmitLoad(gen, locals);
+            this.location.EmitLoad(gen, fields);
             foreach (Expression expr in exprs)
             {
                 expr.Emit(gen);
@@ -81,9 +81,9 @@ namespace mbasic
             gen.Emit(OpCodes.Call, setMethod);
         }
 
-        public override void EmitLoad(ILGenerator gen, List<LocalBuilder> locals)
+        public override void EmitLoad(ILGenerator gen, IList<FieldBuilder> fields)
         {
-            this.location.EmitLoad(gen, locals);
+            this.location.EmitLoad(gen, fields);
             foreach (Expression expr in exprs)
             {
                 expr.Emit(gen);
index 79f87bb..bff56b0 100644 (file)
@@ -11,7 +11,7 @@ namespace mbasic
         public abstract BasicType BasicType { get; }
         public abstract void ConstrainType(SymbolTable symbols, bool isArray, int numDimensions);
         public virtual void ConstrainType(SymbolTable symbols) { ConstrainType(symbols, false, -1); }
-        public abstract void EmitStore(ILGenerator gen, List<LocalBuilder> locals, Expression value);
-        public abstract void EmitLoad(ILGenerator gen, List<LocalBuilder> locals);
+        public abstract void EmitStore(ILGenerator gen, IList<FieldBuilder> fields, Expression value);
+        public abstract void EmitLoad(ILGenerator gen, IList<FieldBuilder> fields);
     }
 }
index 3c980ce..f00f137 100644 (file)
@@ -32,8 +32,8 @@ using System.Diagnostics;
 namespace mbasic
 {
     using LabelList = System.Collections.Generic.SortedList<string, Label>;
-    using TIBasicRuntime;
-    using File = System.IO.File;
+    using TiBasicRuntime;
+
     class Program
     {
         static readonly MethodInfo popMethod =
@@ -42,7 +42,7 @@ namespace mbasic
         static void Main(string[] args)
         {
             bool debug = true;
-            bool runit = false;
+            bool runit = true;
 
             string fileName = args[0];
             string assemblyName = Path.GetFileNameWithoutExtension(fileName);
@@ -75,51 +75,43 @@ namespace mbasic
             }
             ModuleBuilder mbldr = bldr.DefineDynamicModule(moduleName, exeName, debug);
 
+
             TypeBuilder typeBuilder = mbldr.DefineType(assemblyName + ".Program", TypeAttributes.BeforeFieldInit 
-                | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.Abstract);
+                | TypeAttributes.Sealed | TypeAttributes.AnsiClass );
 
 
 
+            ConstructorBuilder defaultConstructor = typeBuilder.DefineConstructor(
+                MethodAttributes.Public, CallingConventions.Standard, null);
+            ILGenerator cgen = defaultConstructor.GetILGenerator();
+            cgen.Emit(OpCodes.Ldarg_0);
+            cgen.Emit(OpCodes.Call, typeof(System.Object).GetConstructor(new Type[0]));
+            cgen.Emit(OpCodes.Ret);
 
 
             MethodBuilder mthdbldr = typeBuilder.DefineMethod("Main", MethodAttributes.Static | MethodAttributes.Public);
+            MethodBuilder runbldr = typeBuilder.DefineMethod("Run", MethodAttributes.Private);
 
             ILGenerator gen = mthdbldr.GetILGenerator();
+            ILGenerator rgen = runbldr.GetILGenerator();
+
             Node.writer = mbldr.DefineDocument(fileName, Guid.Empty, Guid.Empty, Guid.Empty);
             Node.debug = debug;
             Node.labels = new LabelList();
-            n.RecordLabels(gen);
+            n.RecordLabels(rgen);
 
             n.CheckTypes();
-            // Create local variables
+            // Create fields 
 
-            List<LocalBuilder> locals = new List<LocalBuilder>();
+            List<FieldBuilder> fields = new List<FieldBuilder>();
 
             foreach (Variable v in symbols.Variables)
             {
                 
-                LocalBuilder local = v.EmitDeclare(gen);
-                if (debug) local.SetLocalSymInfo(v.Value);
-                locals.Add(local);
+                FieldBuilder field = v.EmitDeclare(typeBuilder);
+                fields.Add(field);
             }
-            Node.locals = locals;
-
-
-
-            #region Initialize locals
-            // Emit a call to BuiltIns.OptionBase to set
-            // the option base at run-time of BASIC program
-            // this will be used for initializing all arrays
-            MethodInfo setOptionBaseMethod =
-                typeof(BuiltIns).GetMethod("OptionBase");
-            gen.Emit(OpCodes.Ldc_I4, Statement.OptionBase);
-            gen.Emit(OpCodes.Call, setOptionBaseMethod);
-            for (int i = 0; i < symbols.Count; i++)
-            {
-                symbols[i].EmitDefaultValue(gen, locals[i]);
-            }
-
-            #endregion Intialize strings
+            Node.fields = fields;
 
             #region Create Static DATA data
             if (data.Count > 0)
@@ -155,39 +147,65 @@ namespace mbasic
             }
             #endregion
 
-            Node.returnSwitch = gen.DefineLabel();
+            #region Create Instance of Program and Invoke Run
+            gen.Emit(OpCodes.Newobj, defaultConstructor);
+            gen.Emit(OpCodes.Call, runbldr);
+            gen.Emit(OpCodes.Ret);
+            gen = null;
+            #endregion
+
+            #region Emit Run Method
+
+            #region Initialize fields
+            // Emit a call to BuiltIns.OptionBase to set
+            // the option base at run-time of BASIC program
+            // this will be used for initializing all arrays
+            MethodInfo setOptionBaseMethod =
+                typeof(BuiltIns).GetMethod("OptionBase");
+            rgen.Emit(OpCodes.Ldc_I4, Statement.OptionBase);
+            rgen.Emit(OpCodes.Call, setOptionBaseMethod);
+            for (int i = 0; i < symbols.Count; i++)
+            {
+                symbols[i].EmitDefaultValue(rgen, fields[i]);
+            }
+
+            #endregion Intialize fields
+
+
+
+            Node.returnSwitch = rgen.DefineLabel();
             // Emit try
-            Label end = gen.BeginExceptionBlock();
+            Label end = rgen.BeginExceptionBlock();
             Node.endLabel = end;
 
-            n.Emit(gen);
+            n.Emit(rgen);
 
             #region Emit Return Switch for GOSUB/RETURN
-            gen.MarkSequencePoint(Node.writer, Int32.MaxValue, -1, Int32.MaxValue, -1);
+            rgen.MarkSequencePoint(Node.writer, Int32.MaxValue, -1, Int32.MaxValue, -1);
 
-            Label exitLabel = gen.DefineLabel();
-            gen.Emit(OpCodes.Br, exitLabel);
+            Label exitLabel = rgen.DefineLabel();
+            rgen.Emit(OpCodes.Br, exitLabel);
 
-            gen.MarkLabel(Node.returnSwitch);
+            rgen.MarkLabel(Node.returnSwitch);
 
-            gen.Emit(OpCodes.Call, popMethod);
-            gen.Emit(OpCodes.Switch, Node.returnLabels.ToArray());
+            rgen.Emit(OpCodes.Call, popMethod);
+            rgen.Emit(OpCodes.Switch, Node.returnLabels.ToArray());
 
-            gen.MarkLabel(exitLabel);
+            rgen.MarkLabel(exitLabel);
             #endregion
 
             // Emit catch
-            gen.BeginCatchBlock(typeof(Exception));
+            rgen.BeginCatchBlock(typeof(Exception));
             MethodInfo getMessageMethod = typeof(Exception).GetMethod("get_Message");
-            gen.Emit(OpCodes.Call, getMessageMethod);
+            rgen.Emit(OpCodes.Call, getMessageMethod);
             MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
-            gen.Emit(OpCodes.Call, writeLineMethod);
-            gen.EndExceptionBlock();
-
-            gen.MarkSequencePoint(Node.writer, Int32.MaxValue, -1, Int32.MaxValue, -1);
-            gen.Emit(OpCodes.Ret);
+            rgen.Emit(OpCodes.Call, writeLineMethod);
+            rgen.EndExceptionBlock();
 
+            rgen.MarkSequencePoint(Node.writer, Int32.MaxValue, -1, Int32.MaxValue, -1);
+            rgen.Emit(OpCodes.Ret);
 
+            #endregion Run Method
 
 
             Type program = typeBuilder.CreateType();
index b45c501..6b4bef4 100644 (file)
@@ -23,7 +23,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection.Emit;
 using System.Reflection;
-using TIBasicRuntime;
+using TiBasicRuntime;
 
 namespace mbasic.SyntaxTree
 {
@@ -61,7 +61,7 @@ namespace mbasic.SyntaxTree
             if (!labelSetAlready) MarkLabel(gen);
             MarkSequencePoint(gen);
 
-            location.EmitStore(gen, locals, value);
+            location.EmitStore(gen, fields, value);
             return;
         }
 
index 4e901af..da6af0a 100644 (file)
@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection;
 using System.Reflection.Emit;
-using TIBasicRuntime;
+using TiBasicRuntime;
 namespace mbasic.SyntaxTree
 {
     class BuiltInsMethodCall : Expression
index cc8aeb3..a83f37b 100644 (file)
@@ -24,7 +24,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection.Emit;
 using System.Reflection;
-using TIBasicRuntime;
+using TiBasicRuntime;
 namespace mbasic.SyntaxTree
 {
     class Function : Expression
index d73bf1d..c5f569b 100644 (file)
@@ -24,7 +24,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection.Emit;
 using System.Reflection;
-using TIBasicRuntime;
+using TiBasicRuntime;
 namespace mbasic.SyntaxTree
 {
     class Gosub : Statement
index 320d05a..d52b405 100644 (file)
@@ -24,7 +24,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection;
 using System.Reflection.Emit;
-using TIBasicRuntime;
+using TiBasicRuntime;
 
 namespace mbasic.SyntaxTree
 {
index 3e4b5c4..963ac1c 100644 (file)
@@ -33,7 +33,7 @@ using System.Reflection;
     internal abstract class Node
     {
         public static SymbolTable symbols;
-        public static List<LocalBuilder> locals;
+        public static List<FieldBuilder> fields;
         public static Lexer lexer;
         public static LabelList labels;
         public static List<Label> returnLabels = new List<Label>();// these are the labels that mark lines after gosub statements. 
index ccd2857..34c2c2f 100644 (file)
@@ -23,7 +23,7 @@ namespace mbasic.SyntaxTree
     using System;
     using System.Collections.Generic;
     using System.Reflection.Emit;
-    using TIBasicRuntime;
+    using TiBasicRuntime;
 
     class OnGoto : Statement
     {
index ddb17a8..41b1d03 100644 (file)
@@ -24,7 +24,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection.Emit;
 using System.Reflection;
-using TIBasicRuntime;
+using TiBasicRuntime;
 namespace mbasic.SyntaxTree
 {
     internal class Print : Statement
index b78513e..a5b022d 100644 (file)
@@ -24,7 +24,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection;
 using System.Reflection.Emit;
-using TIBasicRuntime;
+using TiBasicRuntime;
 
 namespace mbasic.SyntaxTree
 {
index 8a34e70..442e541 100644 (file)
@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection.Emit;
 using System.Reflection;
-using TIBasicRuntime;
+using TiBasicRuntime;
 
 namespace mbasic.SyntaxTree
 {
index 48c5212..b6c08ee 100644 (file)
@@ -24,7 +24,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection.Emit;
 using System.Reflection;
-using TIBasicRuntime;
+using TiBasicRuntime;
 
 namespace mbasic.SyntaxTree
 {
index d421bfd..1ae7dbf 100644 (file)
@@ -23,7 +23,7 @@ using System.Collections.Generic;
 using System.Text;
 using System.Reflection.Emit;
 using System.Reflection;
-using TIBasicRuntime;
+using TiBasicRuntime;
 
 namespace mbasic.SyntaxTree
 {
index ee63a94..b9f0a7f 100644 (file)
@@ -39,7 +39,7 @@ namespace mbasic.SyntaxTree
 
         public override void Emit(ILGenerator gen)
         {
-            location.EmitLoad(gen, locals);
+            location.EmitLoad(gen, fields);
             //if (index < 255)
             //{
             //    switch (index)
index b035a05..c7f8d71 100644 (file)
@@ -39,7 +39,6 @@ internal enum Token
     Base,
     Call,
     Data,
-    Def,
     Dim,
     Else,
     End, // used for keywords END and STOP
index fc544d1..d1d158e 100644 (file)
@@ -24,7 +24,8 @@ using System.Collections.Generic;
 using System.Text;
 using mbasic.SyntaxTree;
 using System.Reflection.Emit;
-using TIBasicRuntime;
+using TiBasicRuntime;
+using System.Reflection;
 
 namespace mbasic
 {
@@ -86,35 +87,38 @@ namespace mbasic
             ConstrainType(true, dims.Length);
         }
 
-        public LocalBuilder EmitDeclare(ILGenerator gen)
+        public static readonly FieldAttributes fieldAttributes =
+            FieldAttributes.Private;
+        public FieldBuilder EmitDeclare(TypeBuilder typeBldr)
         {
-            LocalBuilder local;
+            FieldBuilder field;
             switch (dataType)
             {
                 case BasicType.Number:
-                    local = gen.DeclareLocal(typeof(double));
+                    field = typeBldr.DefineField(this.name, typeof(double), fieldAttributes);
                     break;
                 case BasicType.NumberArray:
                     clrArrayType = Type.GetType("System.Double[" + new String(',', dimensions.Length - 1) + "]");
-                    local = gen.DeclareLocal(clrArrayType);
+                    field = typeBldr.DefineField(this.name, clrArrayType, fieldAttributes);
                     break;
                 case BasicType.String:
-                    local = gen.DeclareLocal(typeof(string));
+                    field = typeBldr.DefineField(this.name, typeof(string), fieldAttributes);
                     break;
                 case BasicType.StringArray:
                     clrArrayType = Type.GetType("System.String[" + new String(',', dimensions.Length - 1) + "]");
-                    local = gen.DeclareLocal(clrArrayType);
+                    field = typeBldr.DefineField(this.name, clrArrayType, fieldAttributes);
                     break;
                 default:
                     throw new InvalidOperationException("type not defined for variable");
             }
-            return local;
+            return field;
         }
 
-        public void EmitDefaultValue(ILGenerator gen, LocalBuilder local)
+        public void EmitDefaultValue(ILGenerator gen, FieldBuilder field)
         {
             if (dimensions != null)
             {
+                gen.Emit(OpCodes.Ldarg_0);
                 gen.Emit(OpCodes.Ldc_I4, dimensions.Length);
                 gen.Emit(OpCodes.Newarr, typeof(int));
                 for (int i = 0; i < dimensions.Length; i++)
@@ -133,11 +137,12 @@ namespace mbasic
                 switch (dataType)
                 {
                     case BasicType.String:
+                        gen.Emit(OpCodes.Ldarg_0);
                         gen.Emit(OpCodes.Ldstr, "");
                         break;
                 }
             }
-            if (dataType != BasicType.Number) gen.Emit(OpCodes.Stloc, local);
+            if (dataType != BasicType.Number) gen.Emit(OpCodes.Stfld, field);
         }
 
     }
index d5b1dc8..b6814d8 100644 (file)
@@ -27,20 +27,27 @@ namespace mbasic
             basicType = symbols[symbolIndex].BasicType;
         }
 
-        public override void EmitStore(ILGenerator gen, List<LocalBuilder> locals, Expression value)
+        public override void EmitStore(ILGenerator gen, IList<FieldBuilder> fields, Expression value)
         {
+            gen.Emit(OpCodes.Ldarg_0);
+            // Emit the code to generate the value for the given expression
             value.Emit(gen);
+
+            // Convert booleans (which are used internally for Booleans) to doubles
+            // which is how they are stored in TIBasic. Plus it needs to be negated.
             if (value.GetBasicType() == BasicType.Boolean)
             {
                 gen.Emit(OpCodes.Conv_R8);
                 gen.Emit(OpCodes.Neg);
             }
-            gen.Emit(OpCodes.Stloc, locals[symbolIndex]);
+
+            gen.Emit(OpCodes.Stfld, fields[symbolIndex]);
         }
 
-        public override void EmitLoad(ILGenerator gen, List<LocalBuilder> locals)
+        public override void EmitLoad(ILGenerator gen, IList<FieldBuilder> fields)
         {
-            gen.Emit(OpCodes.Ldloc, locals[symbolIndex]);
+            gen.Emit(OpCodes.Ldarg_0);
+            gen.Emit(OpCodes.Ldfld, fields[symbolIndex]);
         }
 
     }
index ec384b0..0ebf87d 100644 (file)
@@ -2,7 +2,7 @@
   <PropertyGroup>\r
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
-    <ProductVersion>8.0.50727</ProductVersion>\r
+    <ProductVersion>9.0.20706</ProductVersion>\r
     <SchemaVersion>2.0</SchemaVersion>\r
     <ProjectGuid>{3CA4DBDE-9A36-4275-AF39-A6EEFFB5589D}</ProjectGuid>\r
     <OutputType>Exe</OutputType>\r
@@ -38,6 +38,8 @@
   <ItemGroup>\r
     <Reference Include="System" />\r
     <Reference Include="System.Data" />\r
+    <Reference Include="System.Drawing" />\r
+    <Reference Include="System.Windows.Forms" />\r
     <Reference Include="System.Xml" />\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="..\samples\secretnum.mbas">\r
       <Link>samples\secretnum.mbas</Link>\r
     </None>\r
+    <None Include="..\samples\simple.mbas">\r
+      <Link>samples\simple.mbas</Link>\r
+    </None>\r
     <None Include="..\samples\testPrint.mbas">\r
       <Link>samples\testPrint.mbas</Link>\r
     </None>\r