private LuryObject CallUnaryOperator(string op, LuryObject subject) { subject = Dereference(subject); var @operator = subject.GetMember(op, currentContext); return(LuryFunction.Call(@operator, subject)); }
public override LuryObject VisitUnary_expression(LuryParser.Unary_expressionContext context) { if (context.Op == null) { var obj = VisitPostfix_expression(context.RefRight); if (context.Ref != null) { return(obj); } var testObj = Dereference(obj) as LuryFunction; return(testObj != null ? LuryFunction.Call(testObj) : obj); } var result = VisitUnary_expression(context.Right); var reference = result as LuryReference; var op = context.Op; switch (op.Text) { case "++": if (reference == null) { throw new InvalidOperationException(); } return(reference.Assign(currentContext, CallUnaryOperator(IntrinsicConstants.OperatorInc, result))); case "--": if (reference == null) { throw new InvalidOperationException(); } return(reference.Assign(currentContext, CallUnaryOperator(IntrinsicConstants.OperatorDec, result))); case "+": return(CallUnaryOperator(IntrinsicConstants.OperatorPos, result)); case "-": return(CallUnaryOperator(IntrinsicConstants.OperatorNeg, result)); case "!": return(CallUnaryOperator(IntrinsicConstants.OperatorInv, result)); default: throw new InvalidOperationException(); } }
public override LuryObject VisitFunction_definition(LuryParser.Function_definitionContext context) { var name = context.Name.Text; var parameter = context.Parameter == null? Enumerable.Empty <string>() : ((List <LuryObject>)VisitParameter(context.Parameter).Value).Select(_ => (string)_.Value); var functionInfo = new UserFunctionInfo(context.FunctionSuite, currentContext, parameter); var function = LuryFunction.GetObject(functionInfo); return(currentContext[name] = function); }
public override LuryObject VisitPostfix_expression(LuryParser.Postfix_expressionContext context) { if (context.Left == null) { return(VisitChildren(context)); } var left = VisitPostfix_expression(context.Left); if (context.Dot != null) { return(LuryReference.Create(Dereference(left), context.Dot.Text)); } if (context.Op != null) { var result = Dereference(left); var reference = left as LuryReference; if (reference == null) { throw new InvalidOperationException(); } reference.Assign(currentContext, context.Op.Text == "++" ? CallUnaryOperator(IntrinsicConstants.OperatorInc, result) : CallUnaryOperator(IntrinsicConstants.OperatorDec, result)); return(result); } if (context.Key != null) { return(LuryReference.Create(Dereference(left), VisitKey(context.Key))); } if (context.Call != null) { if (context.Arguments == null) { return(LuryFunction.Call(Dereference(left))); } var arguments = VisitArgument(context.Arguments); return(LuryFunction.Call(Dereference(left), ((List <LuryObject>)arguments.Value).ToArray())); } throw new InvalidOperationException(); }
public override LuryObject VisitFor_statement(LuryParser.For_statementContext context) { // for block var forCount = 0; currentContext = new LuryContext(currentContext); try { var @object = VisitExpression(context.Object); var iterator = LuryFunction.Call(@object.GetMember(IntrinsicConstants.FunctionIterate, currentContext), @object); var moveNext = LuryFunction.Call(iterator.GetMember(IntrinsicConstants.FunctionMoveNext, currentContext), iterator); var variable = context.Variable.Text; LuryObject forReturn = null; while (moveNext.Equals(LuryBoolean.True)) { forCount++; var fetchedValue = LuryFunction.Call(iterator.GetMember(IntrinsicConstants.FunctionFetch, currentContext), iterator); currentContext[variable] = fetchedValue; forReturn = VisitSuite(context.ForSuite); moveNext = LuryFunction.Call(iterator.GetMember(IntrinsicConstants.FunctionMoveNext, currentContext), iterator); } if (forCount > 0) { return(forReturn); } } finally { currentContext = currentContext.Parent; } // else block if (forCount <= 0 || context.ElseSuite == null) { return(null); } LuryObject elseReturn; currentContext = new LuryContext(currentContext); try { elseReturn = VisitSuite(context.ElseSuite); } finally { currentContext = currentContext.Parent; } return(elseReturn); }
public static LuryContext CreateGlobalContext() { var context = new LuryContext(); #region Intrinsic Classes Action <string, string, IEnumerable <Tuple <string, MethodInfo> > > setFunctionMember = (t, n, f) => { var type = new LuryObject(t, null); foreach (var item in f) { type.SetMember(item.Item1, new LuryObject(LuryFunction.FullName, item.Item2, true)); } type.Freeze(); context[n] = type; context[type.LuryTypeName] = type; }; var intrinsicTypes = Assembly .GetExecutingAssembly() .GetTypes() .Where(t => t.IsClass && Attribute.GetCustomAttribute(t, typeof(IntrinsicClassAttribute)) != null); foreach (var type in intrinsicTypes) { var attr = type.GetCustomAttribute <IntrinsicClassAttribute>(); var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); var funcnames = methods .Select( method => new { method, attributes = method.GetCustomAttributes <IntrinsicAttribute>().Select(a => a.TargetFunction) }) .SelectMany(_ => _.attributes, (_, funcName) => Tuple.Create(funcName, _.method)).ToList(); if (funcnames.Count > 0) { setFunctionMember(attr.FullName, attr.TypeName, funcnames); } } #endregion #region BuiltIn Functions var builtInFunctions = Assembly .GetExecutingAssembly() .GetTypes() .Where(t => t.IsClass && Attribute.GetCustomAttribute(t, typeof(BuiltInClass)) != null); foreach (var type in builtInFunctions) { var attr = type.GetCustomAttribute <BuiltInClass>(); var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public); var funcnames = methods .Select( method => new { method, attributes = method.GetCustomAttributes <BuiltInAttribute>().Select(a => a.FunctionName) }) .SelectMany(_ => _.attributes, (_, funcName) => Tuple.Create(funcName, _.method)).ToList(); foreach (var func in funcnames) { context[func.Item1] = LuryFunction.GetObject(func.Item2); } } #endregion return(context); }
public static void SetBuiltInFunctions(LuryObject obj) { obj["println"] = new LuryFunction(PrintLine); obj["print"] = new LuryFunction(Print); }