public void Algebraic2() { var src = @" type TestType Small of int Large of int var a = new Small 1 var b = new Large 100 a.Tag + b.Tag"; var result = new NodeBase[] { Expr.Type( "TestType", Expr.Label("Small", "int"), Expr.Label("Large", "int") ), Expr.Var("a", Expr.New("Small", Expr.Int(1))), Expr.Var("b", Expr.New("Large", Expr.Int(100))), Expr.Add( Expr.GetMember(Expr.Get("a"), "Tag"), Expr.GetMember(Expr.Get("b"), "Tag") ) }; TestParser(src, result); }
/// <summary> /// Checks if the expression returns a value and has a specified type. /// </summary> public void CheckTypedExpression(NodeBase node, Type calculatedType = null, bool allowNull = false) { var type = calculatedType ?? node.Resolve(this); if(!allowNull && type == typeof(NullType)) Error(node, CompilerMessages.ExpressionNull); if(type.IsVoid()) Error(node, CompilerMessages.ExpressionVoid); if (type.IsLambdaType()) { var argUnknown = (node as LambdaNode).Arguments.First(x => x.Type == typeof (UnspecifiedType)); Error(node, CompilerMessages.LambdaArgTypeUnknown, argUnknown.Name); } }
public void Algebraic1() { var src = @" type TestType Value of int (new Value 1).Tag"; var result = new NodeBase[] { Expr.Type( "TestType", Expr.Label("Value", "int") ), Expr.GetMember( Expr.New("Value", Expr.Int(1)), "Tag" ) }; TestParser(src, result); }
public static SetMemberNode SetMember(TypeSignature type, string name, NodeBase value) { return(new SetMemberNode { StaticType = type, MemberName = name, Value = value }); }
public static GetMemberNode GetMember(NodeBase expr, string name, params TypeSignature[] hints) { return(new GetMemberNode { Expression = expr, MemberName = name, TypeHints = hints.ToList() }); }
public static SetIdentifierNode Set(string name, NodeBase value) { return(new SetIdentifierNode { Identifier = name, Value = value }); }
public NodeChild(NodeBase node, Action<NodeBase> setter) { Node = node; Setter = setter; }
public static ForeachNode For(Local local, NodeBase from, NodeBase to, CodeBlockNode body) { return(new ForeachNode { Local = local, RangeStart = from, RangeEnd = to, Body = body }); }
public static IfNode If(NodeBase condition, CodeBlockNode ifTrue, CodeBlockNode ifFalse = null) { return(new IfNode { Condition = condition, TrueAction = ifTrue, FalseAction = ifFalse }); }
public void For2() { var src = @" for a in x..y do test ()"; var result = new NodeBase[] { Expr.For( "a", Expr.Get("x"), Expr.Get("y"), Expr.Block( Expr.Invoke("test") ) ) }; TestParser(src, result); }
public void RefFunction2() { var src = @" fun test (a:int x:ref int) -> x = a * 2 var result = 0 test 21 (ref result) result "; var result = new NodeBase[] { Expr.Fun( "test", new [] { Expr.Arg("a", "int"), Expr.Arg("x", "int", true) }, Expr.Set( "x", Expr.Mult(Expr.Get("a"), Expr.Int(2)) ) ), Expr.Var("result", Expr.Int(0)), Expr.Invoke("test", Expr.Int(21), Expr.Ref(Expr.Get("result"))), Expr.Get("result") }; TestParser(src, result); }
public void RefFunction1() { var src = @" var x = 0 int::TryParse ""100"" (ref x) x"; var result = new NodeBase[] { Expr.Var("x", Expr.Int(0)), Expr.Invoke( "int", "TryParse", Expr.Str("100"), Expr.Ref(Expr.Get("x")) ), Expr.Get("x") }; TestParser(src, result); }
public void Records2() { var src = @" record First A : int record Second B : int var a = new First 2 var b = new Second 3 a.A * b.B "; var result = new NodeBase[] { Expr.Record("First", Expr.Field("A", "int")), Expr.Record("Second", Expr.Field("B", "int")), Expr.Var("a", Expr.New("First", Expr.Int(2))), Expr.Var("b", Expr.New("Second", Expr.Int(3))), Expr.Mult( Expr.GetMember(Expr.Get("a"), "A"), Expr.GetMember(Expr.Get("b"), "B") ) }; TestParser(src, result); }
/// <summary> /// Re-infers the lambda if argument types were not specified before. /// </summary> protected static void ensureLambdaInferred(Context ctx, NodeBase canBeLambda, Type delegateType) { var lambda = canBeLambda as LambdaNode; if (lambda == null) return; var wrapper = ReflectionHelper.WrapDelegate(delegateType); if(!wrapper.ReturnType.IsGenericParameter) lambda.SetInferredReturnType(wrapper.ReturnType); lambda.Resolve(ctx); if (lambda.MustInferArgTypes) lambda.SetInferredArgumentTypes(wrapper.ArgumentTypes); }
public static SetMemberNode Dec(NodeBase expr, string mbr, int value = 1) { return(SetMember(expr, mbr, Sub(GetMember(expr, mbr), Int(value)))); }
public static LetNode Let(Local name, NodeBase expr) { return(new LetNode { Local = name, Value = expr }); }
public void MultilineLoop() { var src = @" while a > 0 do a b"; var result = new NodeBase[] { Expr.While( Expr.Greater( Expr.Get("a"), Expr.Int(0) ), Expr.Block(Expr.Get("a")) ), Expr.Get("b") }; TestParser(src, result); }
public static ForeachNode For(Local local, NodeBase seq, CodeBlockNode body) { return(new ForeachNode { Local = local, IterableExpression = seq, Body = body }); }
public void Algebraic3() { var src = @" type TestType Small of int Large of int fun part:TestType (x:int) -> if x > 100 then (new Large x) as TestType else new Small x var a = part 10 new [ a is TestType; a is Small; a is Large ]"; var result = new NodeBase[] { Expr.Type( "TestType", Expr.Label("Small", "int"), Expr.Label("Large", "int") ), Expr.Fun( "part", "TestType", new [] { Expr.Arg("x", "int") }, Expr.If( Expr.Greater(Expr.Get("x"), Expr.Int(100)), Expr.Block( Expr.Cast( Expr.New("Large", Expr.Get("x")), "TestType" ) ), Expr.Block( Expr.New("Small", Expr.Get("x")) ) ) ), Expr.Var("a", Expr.Invoke("part", Expr.Int(10))), Expr.Array( Expr.Is(Expr.Get("a"), "TestType"), Expr.Is(Expr.Get("a"), "Small"), Expr.Is(Expr.Get("a"), "Large") ) }; TestParser(src, result); }
public static UsingNode Using(NodeBase expr, params NodeBase[] stmts) { return(new UsingNode { Expression = expr, Body = Block(stmts) }); }
public void NonInitializedVariable() { var src = @" var a : int a = 1"; var result = new NodeBase[] { Expr.Var("a", "int"), Expr.Set("a", Expr.Int(1)) }; TestParser(src, result); }
public void ComplexWhileTest() { var src = @" use System.Net let listener = new HttpListener () listener.Prefixes.Add ""http://127.0.0.1:8080/"" listener.Prefixes.Add ""http://localhost:8080/"" var count = 1 while true do listener.Start () let ctx = listener.GetContext () let rq = ctx.Request let resp = ctx.Response let respStr = fmt ""Hello from LENS! This page has been viewed {0} times."" count let buf = Encoding::UTF8.GetBytes respStr resp.ContentLength64 = buf.Length let output = resp.OutputStream output.Write buf 0 (buf.Length) output.Close () listener.Stop () count = count + 1 "; var nodes = new NodeBase[] { new UseNode {Namespace = "System.Net"}, Expr.Let("listener", Expr.New("HttpListener")), Expr.Invoke( Expr.GetMember( Expr.GetMember(Expr.Get("listener"), "Prefixes"), "Add" ), Expr.Str("http://127.0.0.1:8080/") ), Expr.Invoke( Expr.GetMember( Expr.GetMember(Expr.Get("listener"), "Prefixes"), "Add" ), Expr.Str("http://localhost:8080/") ), Expr.Var("count", Expr.Int(1)), Expr.While( Expr.True(), Expr.Block( Expr.Invoke(Expr.Get("listener"), "Start"), Expr.Let("ctx", Expr.Invoke(Expr.Get("listener"), "GetContext")), Expr.Let("rq", Expr.GetMember(Expr.Get("ctx"), "Request")), Expr.Let("resp", Expr.GetMember(Expr.Get("ctx"), "Response")), Expr.Let( "respStr", Expr.Invoke( Expr.Get("fmt"), Expr.Str("Hello from LENS! This page has been viewed {0} times."), Expr.Get("count") ) ), Expr.Let( "buf", Expr.Invoke( Expr.GetMember( Expr.GetMember("Encoding", "UTF8"), "GetBytes" ), Expr.Get("respStr") ) ), Expr.SetMember( Expr.Get("resp"), "ContentLength64", Expr.GetMember(Expr.Get("buf"), "Length") ), Expr.Let("output", Expr.GetMember(Expr.Get("resp"), "OutputStream")), Expr.Invoke( Expr.Get("output"), "Write", Expr.Get("buf"), Expr.Int(0), Expr.GetMember(Expr.Get("buf"), "Length") ), Expr.Invoke( Expr.Get("output"), "Close" ), Expr.Invoke( Expr.Get("listener"), "Stop" ), Expr.Inc("count") ) ) }; TestParser(src, nodes); }
public void Records1() { var src = @" record Holder A : int B : int var a = new Holder 2 3 a.A * a.B "; var result = new NodeBase[] { Expr.Record( "Holder", Expr.Field("A", "int"), Expr.Field("B", "int") ), Expr.Var( "a", Expr.New("Holder", Expr.Int(2), Expr.Int(3)) ), Expr.Mult( Expr.GetMember(Expr.Get("a"), "A"), Expr.GetMember(Expr.Get("a"), "B") ) }; TestParser(src, result); }
public static SetIndexNode SetIdx(NodeBase expr, NodeBase index, NodeBase value) { return(new SetIndexNode { Expression = expr, Index = index, Value = value }); }
public static IsOperatorNode Is <T>(NodeBase node) { return(new IsOperatorNode { Expression = node, Type = typeof(T) }); }
public static SetIdentifierNode Set(Local name, NodeBase value) { return(new SetIdentifierNode { Local = name, Value = value }); }
public static BitOperatorNode BitXor(NodeBase left, NodeBase right) { return(new BitOperatorNode { Kind = LogicalOperatorKind.Xor, LeftOperand = left, RightOperand = right }); }
public static SetMemberNode SetMember(NodeBase expr, string name, NodeBase value) { return(new SetMemberNode { Expression = expr, MemberName = name, Value = value }); }
public static BooleanOperatorNode Or(NodeBase left, NodeBase right) { return(new BooleanOperatorNode { Kind = LogicalOperatorKind.Or, LeftOperand = left, RightOperand = right }); }
public static InvocationNode Invoke(NodeBase expr, string name, params NodeBase[] args) { return(Invoke(GetMember(expr, name), args)); }
public static XorOperatorNode Xor(NodeBase left, NodeBase right) { return(Op <XorOperatorNode>(left, right)); }
public static VarNode Var(Local name, NodeBase expr) { return(new VarNode { Local = name, Value = expr }); }
public static ComparisonOperatorNode Compare(ComparisonOperatorKind kind, NodeBase left, NodeBase right) { return(new ComparisonOperatorNode { Kind = kind, LeftOperand = left, RightOperand = right }); }
public static WhileNode While(NodeBase condition, CodeBlockNode body) { return(new WhileNode { Condition = condition, Body = { Statements = body.Statements } }); }
public static ComparisonOperatorNode Equal(NodeBase left, NodeBase right) { return(new ComparisonOperatorNode { LeftOperand = left, RightOperand = right }); }
public static ForeachNode For(string name, NodeBase seq, CodeBlockNode body) { return(new ForeachNode { VariableName = name, IterableExpression = seq, Body = body }); }
public static ComparisonOperatorNode Less(NodeBase left, NodeBase right) { return(new ComparisonOperatorNode { Kind = ComparisonOperatorKind.Less, LeftOperand = left, RightOperand = right }); }
public static ForeachNode For(string name, NodeBase from, NodeBase to, CodeBlockNode body) { return(new ForeachNode { VariableName = name, RangeStart = from, RangeEnd = to, Body = body }); }
public static ComparisonOperatorNode GreaterEqual(NodeBase left, NodeBase right) { return(new ComparisonOperatorNode { Kind = ComparisonOperatorKind.GreaterEquals, LeftOperand = left, RightOperand = right }); }
public static ThrowNode Throw(NodeBase expr) { return(new ThrowNode { Expression = expr }); }
private static T Op <T>(NodeBase left, NodeBase right) where T : BinaryOperatorNodeBase, new() { return(new T { LeftOperand = left, RightOperand = right }); }
public static UsingNode Using(string name, NodeBase expr, params NodeBase[] stmts) { return(new UsingNode { VariableName = name, Expression = expr, Body = Block(stmts) }); }
public static NewObjectArrayNode Array(Type type, NodeBase size) { return(new NewObjectArrayNode { Type = type, Size = size }); }
public void GraphicScript1() { var src = @" fun maker:Rect (x:int y:int) -> let r = new Rect () r.X = (x + 1) * 50 r.Y = (y + 1) * 50 r.Focus = -> r.Fill = System.Windows.Media.Color::FromRgb <| (rand 100 255) as byte <| (rand 100 255) as byte <| (rand 100 255) as byte r let create = (x:int y:int) -> Screen.Add (maker x y) 10.times (x:int -> 10.times (y:int -> create x y)) "; var nodes = new NodeBase[] { Expr.Fun( "maker", "Rect", new [] { Expr.Arg("x", "int"), Expr.Arg("y", "int") }, Expr.Let("r", Expr.New("Rect")), Expr.SetMember( Expr.Get("r"), "X", Expr.Mult( Expr.Add(Expr.Get("x"), Expr.Int(1)), Expr.Int(50) ) ), Expr.SetMember( Expr.Get("r"), "Y", Expr.Mult( Expr.Add(Expr.Get("y"), Expr.Int(1)), Expr.Int(50) ) ), Expr.SetMember( Expr.Get("r"), "Focus", Expr.Lambda( Expr.SetMember( Expr.Get("r"), "Fill", Expr.Invoke( "System.Windows.Media.Color", "FromRgb", Expr.Cast( Expr.Invoke("rand", Expr.Int(100), Expr.Int(255)), "byte" ), Expr.Cast( Expr.Invoke("rand", Expr.Int(100), Expr.Int(255)), "byte" ), Expr.Cast( Expr.Invoke("rand", Expr.Int(100), Expr.Int(255)), "byte" ) ) ) ) ), Expr.Get("r") ), Expr.Let( "create", Expr.Lambda( new [] { Expr.Arg("x", "int"), Expr.Arg("y", "int") }, Expr.Invoke( Expr.Get("Screen"), "Add", Expr.Invoke( "maker", Expr.Get("x"), Expr.Get("y") ) ) ) ), Expr.Invoke( Expr.Int(10), "times", Expr.Lambda( new [] { Expr.Arg("x", "int") }, Expr.Invoke( Expr.Int(10), "times", Expr.Lambda( new [] { Expr.Arg("y", "int") }, Expr.Invoke( "create", Expr.Get("x"), Expr.Get("y") ) ) ) ) ) }; TestParser(src, nodes); }
public static GetIndexNode GetIdx(NodeBase expr, NodeBase index) { return(new GetIndexNode { Expression = expr, Index = index }); }
public void DelegateTypeHints() { var src = new NodeBase[] { Expr.Var("test", Expr.GetMember("string", "Concat", "string", "string")), Expr.Invoke(Expr.Get("test"), Expr.Str("a"), Expr.Str("b")) }; Test(src, "ab"); }
/// <summary> /// Adds a new node to the main script's body. /// </summary> private void declareScriptNode(NodeBase node) { MainMethod.Body.Add(node); }