Example #1
0
        public override void ConstrainType(SymbolTable symbols, 
            bool isArray, int numDimensions)
        {
            location.ConstrainType(symbols, true, exprs.Length);
            foreach (Expression expr in exprs)
            {
                BasicType indexType = expr.GetBasicType();
                if (indexType != BasicType.Number &&
                    indexType != BasicType.Boolean)
                    throw new Exception("type error");
            }
            string commas = new String(',', exprs.Length - 1);
            Type t;
            if (location.BasicType == BasicType.StringArray)
            {
                t = Type.GetType("System.String[" + commas + "]");
            }
            else
            {
                t = Type.GetType("System.Double[" + commas + "]");
            }

            getMethod = t.GetMethod("Get");
            setMethod = t.GetMethod("Set");
        }
Example #2
0
        private static void InitializeReservedWords(SymbolTable symbols)
        {
            // Keywords for statements
            symbols.ReserveWord("BASE", Token.Base);
            symbols.ReserveWord("CALL", Token.Call);
            symbols.ReserveWord("CLEAR", Token.Subroutine);
            symbols.ReserveWord("DATA", Token.Data);
            symbols.ReserveWord("DIM", Token.Dim);
            symbols.ReserveWord("DISPLAY", Token.Print);
            symbols.ReserveWord("ELSE", Token.Else);
            symbols.ReserveWord("END", Token.End);
            symbols.ReserveWord("FOR", Token.For);
            symbols.ReserveWord("GO", Token.Go);
            symbols.ReserveWord("GOSUB", Token.Gosub);
            symbols.ReserveWord("GOTO", Token.Goto);
            symbols.ReserveWord("IF", Token.If);
            symbols.ReserveWord("INPUT", Token.Input);
            symbols.ReserveWord("LET", Token.Let);
            symbols.ReserveWord("NEXT", Token.Next);
            symbols.ReserveWord("ON", Token.On);
            symbols.ReserveWord("OPTION", Token.Option);
            symbols.ReserveWord("PRINT", Token.Print);
            symbols.ReserveWord("READ", Token.Read);
            symbols.ReserveWord("REM", Token.Remark);
            symbols.ReserveWord("RESTORE", Token.Restore);
            symbols.ReserveWord("RETURN", Token.Return);
            symbols.ReserveWord("STOP", Token.End);
            symbols.ReserveWord("SUB", Token.Sub);
            symbols.ReserveWord("TAB", Token.Tab);
            symbols.ReserveWord("THEN", Token.Then);
            symbols.ReserveWord("TO", Token.To);

            // String Functions
            symbols.ReserveWord("ASC", Token.Function);
            symbols.ReserveWord("CHR$", Token.Function);
            symbols.ReserveWord("LEN", Token.Function);
            symbols.ReserveWord("POS", Token.Function);
            symbols.ReserveWord("SEG$", Token.Function);
            symbols.ReserveWord("STR$", Token.Function);
            symbols.ReserveWord("VAL", Token.Function);

            // Number Functions
            symbols.ReserveWord("ABS", Token.Function);
            symbols.ReserveWord("ATN", Token.Function);
            symbols.ReserveWord("COS", Token.Function);
            symbols.ReserveWord("EXP", Token.Function);
            symbols.ReserveWord("INT", Token.Function);
            symbols.ReserveWord("LOG", Token.Function);
            symbols.ReserveWord("RANDOMIZE", Token.Randomize); // actually a statement
            symbols.ReserveWord("RND", Token.Function);
            symbols.ReserveWord("SGN", Token.Function);
            symbols.ReserveWord("SIN", Token.Function);
            symbols.ReserveWord("SQR", Token.Function);
            symbols.ReserveWord("TAN", Token.Function);
        }
Example #3
0
 public Lexer(Stream stream, SymbolTable symbols)
 {
     this.symbols = symbols;
     reader = new Reader(stream);
     startOfLine = true;
 }
Example #4
0
        static void Main(string[] args)
        {
            bool debug = true;
            bool runit = true;

            string fileName = args[0];
            string assemblyName = Path.GetFileNameWithoutExtension(fileName);
            string moduleName = assemblyName + ".exe";
            string exeName = assemblyName + ".exe";

            fileName = Path.GetFullPath(fileName);
            Stream stream = File.OpenRead(fileName);
            SymbolTable symbols = new SymbolTable();
            InitializeReservedWords(symbols);
            SortedList<string, object[]> data = new SortedList<string, object[]>(); // a list used to contain all the statid DATA data.
            Parser parser = new Parser(stream, symbols, data);
            Node.lexer = parser.lexer;
            Node.symbols = symbols;

            Statement n = parser.Parse();

            AppDomain domain = AppDomain.CurrentDomain;
            AssemblyName name = new AssemblyName(assemblyName);
            AssemblyBuilder bldr = domain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);

            if (debug)
            {
                Type daType = typeof(DebuggableAttribute);
                ConstructorInfo daCtor = daType.GetConstructor(new Type[] { typeof(DebuggableAttribute.DebuggingModes) });
                CustomAttributeBuilder daBuilder = new CustomAttributeBuilder(daCtor, new object[] {
                    DebuggableAttribute.DebuggingModes.DisableOptimizations |
                    DebuggableAttribute.DebuggingModes.Default });
                bldr.SetCustomAttribute(daBuilder);
            }
            ModuleBuilder mbldr = bldr.DefineDynamicModule(moduleName, exeName, debug);

            TypeBuilder typeBuilder = mbldr.DefineType(assemblyName + ".Program", TypeAttributes.BeforeFieldInit
                | 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(rgen);

            n.CheckTypes();
            // Create fields

            List<FieldBuilder> fields = new List<FieldBuilder>();

            foreach (Variable v in symbols.Variables)
            {

                FieldBuilder field = v.EmitDeclare(typeBuilder);
                fields.Add(field);
            }
            Node.fields = fields;

            #region Create Static DATA data
            if (data.Count > 0)
            {
                MethodInfo addDataMethod = typeof(BuiltIns).GetMethod("AddData");

                for (int labelIndex = 0; labelIndex < data.Count; labelIndex++)
                {
                    object[] dataList = data.Values[labelIndex];
                    string label = data.Keys[labelIndex];

                    gen.Emit(OpCodes.Ldstr, label);
                    gen.Emit(OpCodes.Ldc_I4, dataList.Length);
                    gen.Emit(OpCodes.Newarr, typeof(object));

                    for (int i = 0; i < dataList.Length; i++)
                    {
                        gen.Emit(OpCodes.Dup); // duplicate array reference, it will be consumed on store element
                        gen.Emit(OpCodes.Ldc_I4, i);
                        object o = dataList[i];
                        if (o is string) gen.Emit(OpCodes.Ldstr, (string)o);
                        else
                        {
                            double d = (double)o;
                            gen.Emit(OpCodes.Ldc_R8, d);
                            gen.Emit(OpCodes.Box, typeof(double));
                        }
                        gen.Emit(OpCodes.Stelem_Ref);
                    }

                    gen.Emit(OpCodes.Call, addDataMethod);
                }
            }
            #endregion

            #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 = rgen.BeginExceptionBlock();
            Node.endLabel = end;

            n.Emit(rgen);

            #region Emit Return Switch for GOSUB/RETURN
            rgen.MarkSequencePoint(Node.writer, Int32.MaxValue, -1, Int32.MaxValue, -1);

            Label exitLabel = rgen.DefineLabel();
            rgen.Emit(OpCodes.Br, exitLabel);

            rgen.MarkLabel(Node.returnSwitch);

            rgen.Emit(OpCodes.Call, popMethod);
            rgen.Emit(OpCodes.Switch, Node.returnLabels.ToArray());

            rgen.MarkLabel(exitLabel);
            #endregion

            // Emit catch
            rgen.BeginCatchBlock(typeof(Exception));
            MethodInfo getMessageMethod = typeof(Exception).GetMethod("get_Message");
            rgen.Emit(OpCodes.Call, getMessageMethod);
            MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
            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();
            bldr.SetEntryPoint(mthdbldr);
            bldr.Save(exeName);

            if (runit)
            {
                program.GetMethod("Main").Invoke(null, new object[0]);
            }
        }
Example #5
0
 public virtual void ConstrainType(SymbolTable symbols)
 {
     ConstrainType(symbols, false, -1);
 }
Example #6
0
 public abstract void ConstrainType(SymbolTable symbols, bool isArray, int numDimensions);
Example #7
0
 public Parser(Stream stream, SymbolTable symbols, SortedList<string, object[]> data)
 {
     lexer = new Lexer(stream, symbols);
     this.data = data;
 }
 public override void ConstrainType(SymbolTable symbols, bool isArray, int numDimensions)
 {
     symbols[symbolIndex].ConstrainType(isArray, numDimensions);
     basicType = symbols[symbolIndex].BasicType;
 }