Example #1
0
        /// <summary>
        /// Sets a value on a member of a basic type.
        /// </summary>
        /// <param name="ctx">The context of the runtime</param>
        /// <param name="varExp">The expression representing the index of the instance to set</param>
        /// <param name="valExp">The expression representing the value to set</param>
        /// <param name="node">The assignment ast node</param>
        public static void SetIndexValue(Context ctx, IAstVisitor visitor, AstNode node, Expr varExp, Expr valExp)
        {
            // 1. Get the value that is being assigned.
            var val = valExp.Evaluate(visitor) as LObject;

            // 2. Check the limit if string.
            ctx.Limits.CheckStringLength(node, val);

            // 3. Evaluate expression to get index info.
            var indexExp = varExp.Evaluate(visitor) as IndexAccess;
            if (indexExp == null)
                throw ComLib.Lang.Helpers.ExceptionHelper.BuildRunTimeException(node, "Value to assign is null");

            // 4. Get the target of the index access and the name / number to set.
            var target = indexExp.Instance;
            var memberNameOrIndex = indexExp.MemberName;

            // Get methods associated with type.
            var methods = ctx.Methods.Get(target.Type);

            // Case 1: users[0] = 'kishore'
            if (target.Type == LTypes.Array)
            {
                var index = Convert.ToInt32(((LNumber)memberNameOrIndex).Value);
                methods.SetByNumericIndex(target, index, val);
            }
            // Case 2: users['total'] = 20
            else if (target.Type == LTypes.Map)
            {
                var name = ((LString)memberNameOrIndex).Value;
                methods.SetByStringMember(target, name, val);
            }
        }
Example #2
0
        /// <summary>
        /// Initialize
        /// </summary>
        public Interpreter()
        {
            _settings = new LangSettings();

            // Initialzie the context.
            _context = new Context();
            _context.Settings = _settings;
            _context.Limits.Init();

            _memory = _context.Memory;
            _parser = new Parser(_context);
            _parser.Settings = _settings;
            InitSystemFunctions();
        }
Example #3
0
        /// <summary>
        /// Call a function by passing in all the values.
        /// </summary>
        /// <param name="ctx">The context of the runtime</param>
        /// <param name="functionName">The name of the function to call.</param>
        /// <param name="paramListExpressions">List of parameters as expressions to evaluate first to actual values</param>
        /// <param name="paramVals">List to store the resolved paramter expressions. ( these will be resolved if paramListExpressions is supplied and resolveParams is true. If 
        /// resolveParams is false, the list is assumed to have the values for the paramters to the function.</param>
        /// <param name="resolveParams">Whether or not to resolve the list of parameter expression objects</param>
        /// <returns></returns>
        public static object CallFunctionInScript(Context ctx, FunctionExpr function, string functionName, List<Expr> paramListExpressions, List<object> paramVals, bool resolveParams)
        {
            // 1. Determine if any parameters provided.
            var hasParams = paramListExpressions != null && paramListExpressions.Count > 0;

            // 2. Resolve parameters if necessary
            if (resolveParams && function != null && (function.HasArguments || hasParams))
                ParamHelper.ResolveParametersForScriptFunction(function.Meta, paramListExpressions, paramVals);

            // 3. Assign the argument values to the function and evaluate.
            function.ArgumentValues = paramVals;
            function.Evaluate();

            object result = null;
            if (function.HasReturnValue)
                result = function.ReturnValue;
            else
                result = LObjects.Null;
            return result;
        }
Example #4
0
        /// <summary>
        /// Executes each phase supplied.
        /// </summary>
        /// <param name="script">The script to execute</param>
        /// <param name="phaseCtx">Contextual information passed to all phases.</param>
        /// <param name="ctx">The context of the runtime</param>
        /// <param name="phases">The list of phases.</param>
        /// <returns></returns>
        public PhaseResult Execute(string script, PhaseContext phaseCtx, Context ctx, List<IPhase> phases)
        {
            if (phases == null || phases.Count == 0)
                throw new ArgumentException("No phases supplied to execute");

            // 2. Keep track of last phase result
            PhaseResult lastPhaseResult = null;
            foreach (var phase in phases)
            {
                // 3. Execute the phase and get it's result.
                phase.Ctx = ctx;
                lastPhaseResult = phase.Execute(phaseCtx);
                phase.Result = lastPhaseResult;

                // 4. Stop the phase execution.
                if (!phase.Result.Success)
                {
                    break;
                }
            }
            return lastPhaseResult;
        }
Example #5
0
        /// <summary>
        /// Calls an internal function or external function.
        /// </summary>
        /// <param name="ctx">The context of the runtime.</param>
        /// <param name="fexpr">The function call expression</param>
        /// <param name="functionName">The name of the function. if not supplied, gets from the fexpr</param>
        /// <param name="pushCallStack"></param>
        /// <returns></returns>
        public static object CallFunction(Context ctx, FunctionCallExpr fexpr, string functionName, bool pushCallStack, IAstVisitor visitor)
        {
            if(string.IsNullOrEmpty(functionName))
                functionName = fexpr.NameExp.ToQualifiedName();

            // 1. Check if script func or extern func.
            var isScriptFunc = fexpr.SymScope.IsFunction(functionName);
            var isExternFunc = ctx.ExternalFunctions.Contains(functionName);

            // 2. If neither, this is an error scenario.
            if (!isScriptFunc && !isExternFunc)
                throw ExceptionHelper.BuildRunTimeException(fexpr, "Function does not exist : '" + functionName + "'");

            // 3. Push the name of the function on teh call stack
            if(pushCallStack)
                ctx.State.Stack.Push(functionName, fexpr);

            // 4. Call the function.
            object result = null;
            // Case 1: Custom C# function blog.create blog.*
            if (isExternFunc)
                result = ctx.ExternalFunctions.Call(functionName, fexpr, visitor);

            // Case 2: Script functions "createUser('john');"
            else
            {
                var sym = fexpr.SymScope.GetSymbol(functionName) as SymbolFunction;
                var func = sym.FuncExpr as FunctionExpr;
                result = FunctionHelper.CallFunctionInScript(ctx, func, functionName, fexpr.ParamListExpressions,
                                                             fexpr.ParamList, true, visitor);
            }
            // 3. Finnaly pop the call stact.
            if(pushCallStack)
                ctx.State.Stack.Pop();

            result = CheckConvert(result);
            return result;
        }
Example #6
0
        /// <summary>
        /// Sets a value on a member of a basic type.
        /// </summary>
        /// <param name="ctx">The context of the runtime</param>
        /// <param name="varExp">The expression representing the index of the instance to set</param>
        /// <param name="valExp">The expression representing the value to set</param>
        /// <param name="node">The assignment ast node</param>
        public static void SetMemberValue(Context ctx, IAstVisitor visitor, AstNode node, Expr varExp, Expr valExp)
        {
            // 1. Get the value that is being assigned.
            var val = valExp.Evaluate(visitor) as LObject;

            // 2. Check the limit if string.
            ctx.Limits.CheckStringLength(node, val);

            // 3. Evaluate expression to get index info.
            var memAccess = varExp.Evaluate(visitor) as MemberAccess;
            if (memAccess == null)
                throw ComLib.Lang.Helpers.ExceptionHelper.BuildRunTimeException(node, "Value to assign is null");

            // Case 1: Set member on basic type
            if (memAccess.Type != null)
            {
                // Get methods associated with type.
                var methods = ctx.Methods.Get(memAccess.Type);

                // Case 1: users['total'] = 20
                if (memAccess.Type == LTypes.Map)
                {
                    var target = memAccess.Instance as LObject;
                    methods.SetByStringMember(target, memAccess.MemberName, val);
                }
            }
            // Case 2: Set member on custom c# class
            else if (memAccess.DataType != null)
            {
                if (memAccess.Property != null)
                {
                    var prop = memAccess.Property;
                    prop.SetValue(memAccess.Instance, val.GetValue(prop.PropertyType), null); //fix
                }
            }
        }
Example #7
0
        /// <summary>
        /// Execute a member call.
        /// </summary>
        /// <param name="ctx">The context of the script</param>
        /// <param name="memberAccess">Object to hold all the relevant information required for the member call.</param>
        /// <param name="paramListExpressions">The expressions to resolve as parameters</param>
        /// <param name="paramList">The list of parameters.</param>
        /// <returns></returns>
        public static object CallMemberOnClass(Context ctx, AstNode node, MemberAccess memberAccess, List<Expr> paramListExpressions, List<object> paramList, IAstVisitor visitor)
        {
            object result = LObjects.Null;
            var obj = memberAccess.Instance;
            var type = memberAccess.DataType;

            // Case 1: Property access
            if (memberAccess.Property != null)
            {
                var prop = type.GetProperty(memberAccess.MemberName);
                if (prop != null)
                    result = prop.GetValue(obj, null);
            }
            // Case 2: Method call.
            else if( memberAccess.Method != null)
            {
                result = FunctionHelper.MethodCall(ctx, obj, type, memberAccess.Method, paramListExpressions, paramList, true, visitor);
            }
            // Case 1: Property access
            if (memberAccess.Field != null)
            {
                result = memberAccess.Field.GetValue(obj);
            }
            result = CheckConvert(result);
            return result;
        }
Example #8
0
        /// <summary>
        /// Dynamically invokes a method call.
        /// </summary>
        /// <param name="ctx">Context of the script</param>
        /// <param name="obj">Instance of the object for which the method call is being applied.</param>
        /// <param name="datatype">The datatype of the object.</param>
        /// <param name="methodInfo">The method to call.</param>
        /// <param name="paramListExpressions">List of expressions representing parameters for the method call</param>
        /// <param name="paramList">The list of values(evaluated from expressions) to call.</param>
        /// <param name="resolveParams">Whether or not to resolve the parameters from expressions to values.</param>
        /// <returns></returns>
        private static object MethodCall(Context ctx, object obj, Type datatype, MethodInfo methodInfo, List<Expr> paramListExpressions, List<object> paramList, bool resolveParams, IAstVisitor visitor)
        {
            // 1. Convert language expressions to values.
            if (resolveParams)
                ParamHelper.ResolveParametersForMethodCall(methodInfo, paramListExpressions, paramList, visitor);

            // 2. Convert internal language types to c# code method types.
            object[] args = LangTypeHelper.ConvertArgs(paramList, methodInfo);

            // 3. Handle  params object[];
            if (methodInfo.GetParameters().Length == 1)
            {
                if (methodInfo.GetParameters()[0].ParameterType == typeof(object[]))
                    args = new object[] { args };
            }
            object result = methodInfo.Invoke(obj, args);
            return result;
        }
Example #9
0
        /// <summary>
        /// Call a fluent script function from c#.
        /// </summary>
        /// <param name="context">The context of the call.</param>
        /// <param name="expr">The lambda function</param>
        /// <param name="convertApplicableTypes">Whether or not to convert applicable c# types to fluentscript types, eg. ints and longs to double, List(object) to LArrayType and Dictionary(string, object) to LMapType</param>
        /// <param name="args"></param>
        public static object CallFunctionViaCSharpUsingLambda(Context context, FunctionExpr expr, bool convertApplicableTypes, params object[] args)
        {
            var argsList = args.ToList<object>();
            if (convertApplicableTypes)
                LangTypeHelper.ConvertToLangTypeValues(argsList);
            var execution = new Execution();
            execution.Ctx = context;
            if (EvalHelper.Ctx == null)
                EvalHelper.Ctx = context;

            var result = FunctionHelper.CallFunctionInScript(context, expr, expr.Meta.Name, null, argsList, false, execution);
            return result;
        }
Example #10
0
        /// <summary>
        /// Calls a property get
        /// </summary>
        /// <param name="ctx">The context of the runtime</param>
        /// <param name="memberAccess">Object to hold all the relevant information required for the member call.</param>
        /// <param name="paramListExpressions">The collection of parameters as expressions</param>
        /// <param name="paramList">The collection of parameter values after they have been evaluated</param>
        /// <returns></returns>
        public static object CallMemberOnBasicType(Context ctx, AstNode node, MemberAccess memberAccess, List<Expr> paramListExpressions, List<object> paramList, IAstVisitor visitor)
        {
            object result = null;

            // 1. Get methods
            var methods = ctx.Methods.Get(memberAccess.Type);

            // 2. Get object on which method/property is being called on.
            var lobj = (LObject)memberAccess.Instance;

            // 3. Property ?
            if (memberAccess.Mode == MemberMode.PropertyMember)
            {
                result = methods.GetProperty(lobj, memberAccess.MemberName);
            }
            // 4. Method
            else if (memberAccess.Mode == MemberMode.MethodMember)
            {
                object[] args = null;
                if(paramListExpressions != null && paramListExpressions.Count > 0)
                {
                    ParamHelper.ResolveNonNamedParameters(paramListExpressions, paramList, visitor);
                    args = paramList.ToArray();
                }
                result = methods.ExecuteMethod(lobj, memberAccess.MemberName, args);
            }
            result = CheckConvert(result);
            return result;
        }
Example #11
0
        /// <summary>
        /// Sets a value on a member of a basic type.
        /// </summary>
        /// <param name="ctx">The context of the runtime</param>
        /// <param name="node">The assignment ast node</param>
        /// <param name="isDeclaration">Whether or not this is a declaration</param>
        /// <param name="varExp">The expression representing the index of the instance to set</param>
        /// <param name="valExp">The expression representing the value to set</param>
        public static void SetVariableValue(Context ctx, AstNode node, bool isDeclaration, Expr varExp, Expr valExp)
        {
            string varname = ((VariableExpr)varExp).Name;

            // Case 1: var result;
            if (valExp == null)
            {
                ctx.Memory.SetValue(varname, LObjects.Null, isDeclaration);
            }
            // Case 2: var result = <expression>;
            else
            {
                var result = valExp.Evaluate();

                // CHECK_LIMIT:
                ctx.Limits.CheckStringLength(node, result);
                ctx.Memory.SetValue(varname, result, isDeclaration);
            }

            // LIMIT CHECK
            ctx.Limits.CheckScopeCount(varExp);
            ctx.Limits.CheckScopeStringLength(varExp);
        }
Example #12
0
        /// <summary>
        /// Call a fluent script function from c#.
        /// </summary>
        /// <param name="functionName">The name of the function to call</param>
        /// <param name="convertApplicableTypes">Whether or not to convert applicable c# types to fluentscript types, eg. ints and longs to double, List(object) to LArrayType and Dictionary(string, object) to LMapType</param>
        /// <param name="args"></param>
        public static object CallFunctionViaCSharp(Context context, string functionName, bool convertApplicableTypes, params object[] args)
        {
            var argsList = args.ToList<object>();
            if (convertApplicableTypes)
                LangTypeHelper.ConvertToLangTypeValues(argsList);
            var exists = context.Symbols.IsFunc(functionName);
            if (!exists)
                return null;
            var sym = context.Symbols.GetSymbol(functionName) as SymbolFunction;
            var expr = sym.FuncExpr as FunctionExpr;
            var execution = new Execution();
            execution.Ctx = context;
            if (EvalHelper.Ctx == null)
                EvalHelper.Ctx = context;

            var result = FunctionHelper.CallFunctionInScript(context, expr, functionName, null, argsList, false, execution);
            return result;
        }
Example #13
0
 /// <summary>
 /// Initialize the context.
 /// </summary>
 /// <param name="context"></param>
 public Parser(Context context)
     : base(context)
 {
     _tokenIt = new TokenIterator();
 }
Example #14
0
        /// <summary>
        /// Validate the statements for errors.
        /// </summary>
        /// <param name="stmts">Statements to validate</param>
        /// <returns></returns>
        public RunResult Validate(List<Expr> stmts)
        {
            var start = DateTime.Now;
            if (stmts == null || stmts.Count == 0)
                return new RunResult(start, start, true, "No nodes to validate");

            _ctx = stmts[0].Ctx;

            // Reset the errors.
            _errors = new List<ScriptError>();
            _parseStk = new ParseStackManager();

            // Use the visitor to walk the AST tree of statements/expressions
            var visitor = new AstVisitor((astnode1) => Validate(astnode1), (astnode2) =>OnNodeEnd(astnode2));
            visitor.Visit(stmts);

            var end = DateTime.Now;
            // Now check for success.
            bool success = _errors.Count == 0;
            _results = new RunResult(start, end, success, _errors);
            _results.Errors = _errors;
            return _results;
        }
Example #15
0
 /// <summary>
 /// Sets up the reference to token iterator and context
 /// </summary>
 /// <param name="tk"></param>
 /// <param name="ctx"></param>
 public static void Setup(TokenIterator tk, Context ctx, string scriptName)
 {
     _tokenIt = tk;
     _ctx = ctx;
     _scriptName = scriptName;
 }
Example #16
0
 /// <summary>
 /// Executes further Registration actions
 /// </summary>
 /// <param name="ctx">The context of the interperter</param>
 public override void Setup(Context ctx)
 {
     ctx.Types.Register(typeof(File), null);
     ctx.Types.Register(typeof(Files), null);
     ctx.Types.Register(typeof(Dir),  null);
     ctx.Types.Register(typeof(Dirs), null);
 }
Example #17
0
 /// <summary>
 /// Initialize
 /// </summary>
 public ParserBase(Context context)
 {
     _context = context;
     _parseErrors = new List<LangException>();
     _lexer = new Lexer();
     _lexer.SetContext(_context);
     _lexer.Init("");
 }
Example #18
0
        /// <summary>
        /// Finds a matching script function name from the list of strings representing identifiers.
        /// </summary>
        /// <param name="ctx">The context of the script</param>
        /// <param name="ids">List of strings representing identifier tokens</param>
        /// <returns></returns>
        public static FunctionLookupResult MatchFunctionName(Context ctx, List<Tuple<string,int>> ids)
        {
            var names = ids;
            var foundFuncName = string.Empty;
            var found = false;
            var tokenCount = 0;
            var memberMode = MemberMode.FunctionScript;
            for( int ndx = ids.Count - 1; ndx >=0; ndx-- )
            {
                // "refill inventory"
                var possible = ids[ndx];
                string funcName = possible.Item1;
                string funcNameWithUnderScores = funcName.Replace(' ', '_');

                // Case 1: "refill inventory" - exists with spaces
                if (ctx.Symbols.IsFunc(funcName))
                {
                    foundFuncName = funcName;
                }
                // Case 2: "refill_inventory" - replace space with underscore.
                else if (ctx.Symbols.IsFunc(funcNameWithUnderScores))
                {
                    foundFuncName = funcNameWithUnderScores;
                }
                // Case 3: Check external functions
                else if (ctx.ExternalFunctions.Contains(funcName))
                {
                    memberMode = MemberMode.FunctionExternal;
                    foundFuncName = funcName;
                }

                if (!string.IsNullOrEmpty(foundFuncName))
                {
                    found = true;
                    tokenCount = possible.Item2;
                    break;
                }
            }
            // CASE 1: Not found
            if (!found ) return FunctionLookupResult.False;

            // CASE 2: Single word function
            if ((found && tokenCount == 1) && memberMode == MemberMode.FunctionScript)
            {
                var sym = ctx.Symbols.GetSymbol(foundFuncName) as SymbolFunction;
                var func = sym.FuncExpr as FunctionExpr;
                //var func = ctx.Functions.GetByName(foundFuncName);
                // If wildcard return true;
                if (func.Meta.HasWildCard)
                    return new FunctionLookupResult(true, foundFuncName, memberMode) { TokenCount = tokenCount };
                else
                    return FunctionLookupResult.False;
            }

            var result = new FunctionLookupResult()
            {
                Exists = found,
                Name = foundFuncName,
                FunctionMode = memberMode,
                TokenCount = tokenCount
            };
            return result;
        }
Example #19
0
        /// <summary>
        /// Gets a member access object representing the a member access.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="ctx"></param>
        /// <param name="varExp"></param>
        /// <param name="memberName"></param>
        /// <returns></returns>
        public static MemberAccess GetMemberAccess(AstNode node, Context ctx, Expr varExp, string memberName, IAstVisitor visitor)
        {
            var isVariableExp = varExp.IsNodeType(NodeTypes.SysVariable);
            var variableName = isVariableExp ? ((VariableExpr) varExp).Name : string.Empty;

            // CASE 1: External function call "user.create"
            if (isVariableExp && FunctionHelper.IsExternalFunction(ctx.ExternalFunctions, variableName, memberName))
                return new MemberAccess(MemberMode.FunctionExternal) {Name = variableName, MemberName = memberName};

            // CASE 2. Static method call: "Person.Create"
            if (isVariableExp)
            {
                var result = MemberHelper.IsExternalTypeName(ctx.Memory, ctx.Types, variableName);
                if (result.Success)
                    return MemberHelper.GetExternalTypeMember(node, (Type) result.Item, variableName, null, memberName, true);
            }

            // CASE 3: Module
            if (varExp.IsNodeType(NodeTypes.SysVariable))
            {
                var name = varExp.ToQualifiedName();
                if (!ctx.Memory.Contains(name))
                {
                    var modresult = ResolveSymbol(varExp.SymScope, name);
                    if (modresult != null) return modresult;
                }
            }

            // CASE 4: Nested member.
            var res = varExp.Visit(visitor);
            if (res is MemberAccess )
            {
                return res as MemberAccess;
            }

            var obj = res as LObject;
            // Check for empty objects.
            ExceptionHelper.NotNull(node,  obj, "member access");

            var type = obj.Type;

            // Case 3: Method / Property on FluentScript type
            bool isCoreType = obj.Type.IsBuiltInType();
            if (isCoreType)
            {
                var result = MemberHelper.GetLangBasicTypeMember(node, ctx.Methods, obj, memberName);
                return result;
            }

            // CASE 4: Method / Property on External/Host language type (C#)
            var lclass = obj as LClass;
            var lclassType = lclass.Type as LClassType;
            var member = MemberHelper.GetExternalTypeMember(node, lclassType.DataType, variableName, lclass.Value, memberName, false);
            return member;
        }
Example #20
0
 public Limits(Context ctx)
 {
     _ctx = ctx;
 }
Example #21
0
 /// <summary>
 /// Initialize
 /// </summary>
 /// <param name="ctx"></param>
 public FluentPluginHelper(Context ctx)
 {
     _ctx = ctx;
 }
Example #22
0
        /// <summary>
        /// Sets a value on a member of a basic type.
        /// </summary>
        /// <param name="ctx">The context of the runtime</param>
        /// <param name="node">The assignment ast node</param>
        /// <param name="isDeclaration">Whether or not this is a declaration</param>
        /// <param name="varExp">The expression representing the index of the instance to set</param>
        /// <param name="valExp">The expression representing the value to set</param>
        public static void SetVariableValue(Context ctx, IAstVisitor visitor, AstNode node, bool isDeclaration, Expr varExp, Expr valExp)
        {
            string varname = ((VariableExpr)varExp).Name;

            // Case 1: var result;
            if (valExp == null)
            {
                ctx.Memory.SetValue(varname, LObjects.Null, isDeclaration);
            }
            // Case 2: var result = <expression>;
            else
            {
                var result = valExp.Evaluate(visitor);

                // Check for type: e.g. LFunction ? when using Lambda?
                if (result != null && result != LObjects.Null)
                {
                    var lobj = result as LObject;
                    if (lobj != null && lobj.Type.TypeVal == TypeConstants.Function)
                    {
                        // 1. Define the function in global symbol scope
                        ComLib.Lang.Helpers.SymbolHelper.ResetSymbolAsFunction(varExp.SymScope, varname, lobj);
                    }
                }
                // CHECK_LIMIT:
                ctx.Limits.CheckStringLength(node, result);
                ctx.Memory.SetValue(varname, result, isDeclaration);
            }

            // LIMIT CHECK
            ctx.Limits.CheckScopeCount(varExp);
            ctx.Limits.CheckScopeStringLength(varExp);
        }
Example #23
0
 /// <summary>
 /// The context of the program.
 /// </summary>
 public void SetContext(Context ctx)
 {
     _ctx = ctx;
 }
Example #24
0
 /// <summary>
 /// Initialize
 /// </summary>
 /// <param name="text">The text to parse</param>
 public Lexer(string text)
 {
     this._ctx = new Context();
     this.Init(text);
 }
Example #25
0
 /// <summary>
 /// Initialize
 /// </summary>
 /// <param name="ctx">The context containing plugins among other core integration components.</param>
 /// <param name="text">The source code text to lex</param>
 public Lexer(Context ctx, string text)
 {
     this._ctx = ctx;
     this.Init(text);
 }
Example #26
0
 /// <summary>
 /// Initialize
 /// </summary>
 public ParserBase(Context context)
 {
     _context = context;
     _parseErrors = new List<LangException>();
     _lexer = new Lexer(string.Empty);
     _lexer.SetContext(_context);
 }
Example #27
0
 /// <summary>
 /// Executes a setup on the interpreter
 /// </summary>
 /// <param name="ctx"></param>
 public virtual void Setup(Context ctx)
 {
 }