/// <summary> /// Parse Variable declaration statement /// <varDeclarestmt>::= var identifier <type> “ ; “ | var identifier <type>=<expr> “;” /// | var identifier fun =<callexpr> “;” /// var a numeric / var a numeric=8; /// </summary> /// <param name="type"></param> public Stmt ParseVariableDeclStatement(ProcedureBuilder ctx) { GetNext();//remove var if (Current_Token == TOKEN.TOK_UNQUOTED_STRING) { GetNext(); if (Current_Token == TOKEN.TOK_VAR_BOOL || Current_Token == TOKEN.TOK_VAR_STRING || Current_Token == TOKEN.TOK_VAR_NUMBER || Current_Token == TOKEN.TOK_FUNCTION) { SYMBOL_INFO symb = new SYMBOL_INFO(); symb.SymbolName = base.last_str;// last str = variable name (a) string newfnme = base.last_str; symb.Type = (Current_Token == TOKEN.TOK_VAR_BOOL) ? TYPE_INFO.TYPE_BOOL : (Current_Token == TOKEN.TOK_VAR_NUMBER) ? TYPE_INFO.TYPE_NUMERIC : (Current_Token == TOKEN.TOK_FUNCTION) ? TYPE_INFO.TYPE_FUNCTION : TYPE_INFO.TYPE_STRING; GetNext(); // now we are at ; or = ////////////////////////////////////////var a numeric = 8;//////////////////////////////////////// if (Current_Token == TOKEN.TOK_ASSIGN) { ctx.TABLE.Add(symb); if (symb.Type == TYPE_INFO.TYPE_FUNCTION) { GetNext();//remove = GetNext(); string fname = base.last_str; bool check = prog.IsFunction(fname); if (check) { Procedure varfun = null; varfun = (Procedure)prog.GetProc(fname).Clone(); varfun.Name = newfnme; prog.AddFunctionProtoType(newfnme, varfun.TYPE, varfun.m_formals); prog.Add(varfun); while (Current_Token != TOKEN.TOK_SEMI) { GetNext(); } return(null); } } ctx.TABLE.Add(symb); new VariableDeclStatement(symb); GetNext();// remove = bool IsAsync = false; if (Current_Token == TOKEN.TOK_ASYNC) { IsAsync = true; while (Current_Token != TOKEN.TOK_UNQUOTED_STRING) { GetNext(); } } Exp exp = BExpr(ctx); //------------ Do the type analysis ... if (exp.TypeCheck(ctx.Context) != symb.Type) { throw new Exception("in function " + ctx.Name + "\t Type mismatch in assignment"); } // -------------- End of statement ( ; ) is expected if (Current_Token != TOKEN.TOK_SEMI) { throw new Exception("in function" + ctx.Name + "\t; expected"); } if (IsAsync) { GetNext();//GetNext();//remove return n } } return(new AssignmentStatement(symb, exp, IsAsync)); } /////// // var a numeric; else if (Current_Token == TOKEN.TOK_SEMI) { // ----------- Add to the Symbol Table ctx.TABLE.Add(symb); // return the Object of type // VariableDeclStatement // This will just store the Variable name // in the symbol table return(new VariableDeclStatement(symb)); } else { throw new Exception("in function" + ctx.Name + "\t ; expected"); } } else { throw new Exception("in function" + ctx.Name + " \t Invalid DataType \n Numeric,Bool or String is Expected"); } } else { throw new Exception("in function" + ctx.Name + "\t invalid variable declaration or ; expected"); } }
/// <summary> /// <Factor> ::= <numeric> | <string> | true | false | identifier | <callexpr> | “(“ <expr> “)” | {+|-|!} /// </summary> public Exp Factor(ProcedureBuilder ctx) { TOKEN l_token; Exp RetValue = null; if (Current_Token == TOKEN.TOK_NUMERIC) { RetValue = new NumericConstant(GetNumber()); Current_Token = GetToken(); } else if (Current_Token == TOKEN.TOK_STRING) { RetValue = new StringLiteral(last_str); Current_Token = GetToken(); } else if (Current_Token == TOKEN.TOK_BOOL_FALSE || Current_Token == TOKEN.TOK_BOOL_TRUE) { RetValue = new BooleanConstant( Current_Token == TOKEN.TOK_BOOL_TRUE ? true : false); Current_Token = GetToken(); } else if (Current_Token == TOKEN.TOK_OPAREN) { Current_Token = GetToken(); RetValue = BExpr(ctx); // Recurse if (Current_Token != TOKEN.TOK_CPAREN) { Console.WriteLine("Missing Closing Parenthesis\n"); throw new Exception(); } Current_Token = GetToken(); } else if (Current_Token == TOKEN.TOK_PLUS || Current_Token == TOKEN.TOK_SUB) { l_token = Current_Token; Current_Token = GetToken(); RetValue = Factor(ctx); if (l_token == TOKEN.TOK_PLUS) { RetValue = new UnaryPlus(RetValue); } else { RetValue = new UnaryMinus(RetValue); } } else if (Current_Token == TOKEN.TOK_NOT) { l_token = Current_Token; Current_Token = GetToken(); RetValue = Factor(ctx); RetValue = new LogicalNot(RetValue); } else if (Current_Token == TOKEN.TOK_UNQUOTED_STRING) { String str = base.last_str; // if it is not a function..it ought to // be a variable if (!prog.IsFunction(str)) { // // if it is not a function..it ought to // be a variable... SYMBOL_INFO inf = ctx.GetSymbol(str); if (inf == null) { throw new Exception("Undefined symbol"); } GetNext(); return(new Variable(inf)); } // // P can be null , if we are parsing a // recursive function call // Procedure p = prog.GetProc(str); // It is a Function Call // Parse the function invocation // Exp ptr = ParseCallProc(ctx, p); GetNext(); return(ptr); } else { Console.WriteLine("Illegal Token"); throw new Exception(); } return(RetValue); }
/// <summary> /// Ctor to be called when we make a ordinary /// subroutine call /// </summary> /// <param name="proc"></param> /// <param name="actuals"></param> public CallExp(Procedure proc, ArrayList actuals) { m_proc = proc; m_actuals = actuals; }
/// <summary> /// /// </summary> /// <param name="cont"></param> /// <returns></returns> public override SYMBOL_INFO Evaluate(RUNTIME_CONTEXT cont) { if (m_proc != null) { // // This is a Ordinary Function Call // // RUNTIME_CONTEXT ctx = new RUNTIME_CONTEXT(cont.GetProgram()); ArrayList lst = new ArrayList(); //TYPE_INFO clsrcall; foreach (Exp ex in m_actuals) { lst.Add(ex.Evaluate(cont)); } SymbolTable x = cont.TABLE; ///for closure function /// use the previous/saved the symbol table(context) when the clouser function call for the second time :) if (m_proc.clossure != null) { TModule.ClosureSymbol++; // for the function(variable) closure function if (TModule.ClosureSymbol < 2 || TModule.PrewFun != m_proc.Name) { //if (m_proc.IsVariable == true && (TModule.ClosureSymbol >= 2)) //{ return m_proc.clossure.Execute(Procedure.ClosureMentain, lst); } Procedure.ClosureMentain = ctx; m_proc.Execute(ctx, lst); TModule.PrewFun = m_proc.Name; return(m_proc.clossure.Execute(ctx, lst)); } TModule.PrewFun = m_proc.Name; return(m_proc.clossure.Execute(Procedure.ClosureMentain, lst)); //} //else // return m_proc.clossure.Execute(ctx, lst); } return(m_proc.Execute(ctx, lst)); } else { // Recursive function call...by the time we // reach here..whole program has already been // parsed. Lookup the Function name table and // resolve the Address // // m_proc = cont.GetProgram().Find(_procname); // note GetProgram() return the module RUNTIME_CONTEXT ctx = new RUNTIME_CONTEXT(cont.GetProgram()); ArrayList lst = new ArrayList(); foreach (Exp ex in m_actuals) { lst.Add(ex.Evaluate(cont)); } return(m_proc.Execute(ctx, lst)); } }
public DNET_EXECUTABLE_GENERATION_CONTEXT(TModule program, Procedure proc, TypeBuilder bld) { _proc = proc; _bld = bld; _program = program; System.Type[] s = new System.Type[_proc.FORMALS.Count]; int i = 0; foreach (SYMBOL_INFO ts in _proc.FORMALS) { if (ts.Type == TYPE_INFO.TYPE_BOOL) { s[i] = typeof(bool); } else if (ts.Type == TYPE_INFO.TYPE_NUMERIC) { s[i] = typeof(double); } else { s[i] = typeof(string); } i = i + 1; } if (_proc.FORMALS.Count == 0) { s = null; } System.Type ret_type = null; if (_proc.TYPE == TYPE_INFO.TYPE_BOOL) { ret_type = typeof(bool); } else if (_proc.TYPE == TYPE_INFO.TYPE_STRING) { ret_type = typeof(string); } else { ret_type = typeof(double); } if (_proc.m_name.Equals("MAIN")) { //--------- Deleberately set to null // This is to ignore return value of main ret_type = null; _methinfo = _bld.DefineMethod(_proc.Name, MethodAttributes.Public | MethodAttributes.Static, ret_type, s); } else { _methinfo = _bld.DefineMethod(_proc.Name, MethodAttributes.Public | MethodAttributes.Static, ret_type, s); } ILout = _methinfo.GetILGenerator(); }