Mercurial Hosting > luan
comparison src/luan/interp/LuaParser.java @ 32:c3eab5a3ce3c
implement closures
git-svn-id: https://luan-java.googlecode.com/svn/trunk@33 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Fri, 14 Dec 2012 05:40:35 +0000 |
parents | 5cf15507d77e |
children | 8793c71ad47a |
comparison
equal
deleted
inserted
replaced
31:5cf15507d77e | 32:c3eab5a3ce3c |
---|---|
27 final Frame parent; | 27 final Frame parent; |
28 final List<String> symbols = new ArrayList<String>(); | 28 final List<String> symbols = new ArrayList<String>(); |
29 int stackSize = 0; | 29 int stackSize = 0; |
30 int loops = 0; | 30 int loops = 0; |
31 boolean isVarArg = false; | 31 boolean isVarArg = false; |
32 final List<String> upValueSymbols = new ArrayList<String>(); | |
33 final List<UpValue.Getter> upValueGetters = new ArrayList<UpValue.Getter>(); | |
32 | 34 |
33 Frame(Frame parent) { | 35 Frame(Frame parent) { |
34 this.parent = parent; | 36 this.parent = parent; |
35 } | 37 } |
36 } | 38 |
39 int stackIndex(String name) { | |
40 int i = symbols.size(); | |
41 while( --i >= 0 ) { | |
42 if( symbols.get(i).equals(name) ) | |
43 return i; | |
44 } | |
45 return -1; | |
46 } | |
47 | |
48 int upValueIndex(String name) { | |
49 int i = upValueSymbols.size(); | |
50 while( --i >= 0 ) { | |
51 if( upValueSymbols.get(i).equals(name) ) | |
52 return i; | |
53 } | |
54 if( parent==null ) | |
55 return -1; | |
56 i = parent.stackIndex(name); | |
57 if( i != -1 ) { | |
58 upValueGetters.add(new UpValue.StackGetter(i)); | |
59 } else { | |
60 i = parent.upValueIndex(name); | |
61 if( i == -1 ) | |
62 return -1; | |
63 upValueGetters.add(new UpValue.NestedGetter(i)); | |
64 } | |
65 upValueSymbols.add(name); | |
66 return upValueSymbols.size() - 1; | |
67 } | |
68 } | |
69 | |
70 static final UpValue.Getter[] NO_UP_VALUE_GETTERS = new UpValue.Getter[0]; | |
37 | 71 |
38 int nEquals; | 72 int nEquals; |
39 int parens = 0; | 73 int parens = 0; |
40 Frame frame = new Frame(null); | 74 Frame frame = new Frame(null); |
41 | 75 |
74 if( frame.stackSize < symbolsSize() ) | 108 if( frame.stackSize < symbolsSize() ) |
75 frame.stackSize = symbolsSize(); | 109 frame.stackSize = symbolsSize(); |
76 return true; | 110 return true; |
77 } | 111 } |
78 | 112 |
79 int index(String name) { | 113 int stackIndex(String name) { |
80 List<String> symbols = frame.symbols; | 114 return frame.stackIndex(name); |
81 int i = symbols.size(); | |
82 while( --i >= 0 ) { | |
83 if( symbols.get(i).equals(name) ) | |
84 return i; | |
85 } | |
86 return -1; | |
87 } | 115 } |
88 | 116 |
89 boolean popSymbols(int n) { | 117 boolean popSymbols(int n) { |
90 List<String> symbols = frame.symbols; | 118 List<String> symbols = frame.symbols; |
91 while( n-- > 0 ) { | 119 while( n-- > 0 ) { |
92 symbols.remove(symbols.size()-1); | 120 symbols.remove(symbols.size()-1); |
93 } | 121 } |
94 return true; | 122 return true; |
95 } | 123 } |
96 | 124 |
125 int upValueIndex(String name) { | |
126 return frame.upValueIndex(name); | |
127 } | |
128 | |
97 boolean incLoops() { | 129 boolean incLoops() { |
98 frame.loops++; | 130 frame.loops++; |
99 return true; | 131 return true; |
100 } | 132 } |
101 | 133 |
102 boolean decLoops() { | 134 boolean decLoops() { |
103 frame.loops--; | 135 frame.loops--; |
104 return true; | 136 return true; |
105 } | 137 } |
106 | 138 |
139 Chunk newChunk() { | |
140 return new Chunk( (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg, frame.upValueGetters.toArray(NO_UP_VALUE_GETTERS) ); | |
141 } | |
107 | 142 |
108 Rule Target() { | 143 Rule Target() { |
109 return Sequence( | 144 return Sequence( |
110 Spaces(), | 145 Spaces(), |
111 FirstOf( | 146 FirstOf( |
112 Sequence( ExpList(), EOI ), | 147 Sequence( ExpList(), EOI ), |
113 Sequence( | 148 Sequence( |
114 action( frame.isVarArg = true ), | 149 action( frame.isVarArg = true ), |
115 Block(), | 150 Block(), |
116 EOI, | 151 EOI, |
117 push( new Chunk( (Stmt)pop(), frame.stackSize, 0, frame.isVarArg ) ) | 152 push( newChunk() ) |
118 ) | 153 ) |
119 ) | 154 ) |
120 ); | 155 ); |
121 } | 156 } |
122 | 157 |
384 boolean makeSettableVar() { | 419 boolean makeSettableVar() { |
385 Object obj2 = pop(); | 420 Object obj2 = pop(); |
386 if( obj2==null ) | 421 if( obj2==null ) |
387 return false; | 422 return false; |
388 Object obj1 = pop(); | 423 Object obj1 = pop(); |
389 if( obj1==null ) { | 424 if( obj1!=null ) { |
390 String name = (String)obj2; | |
391 int index = index(name); | |
392 if( index == -1 ) { | |
393 push( new SetTableEntry( EnvExpr.INSTANCE, new ConstExpr(name) ) ); | |
394 } else { | |
395 push( new SetLocalVar(index) ); | |
396 } | |
397 } else { | |
398 Expr key = expr(obj2); | 425 Expr key = expr(obj2); |
399 Expr table = expr(obj1); | 426 Expr table = expr(obj1); |
400 push( new SetTableEntry(table,key) ); | 427 return push( new SetTableEntry(table,key) ); |
401 } | 428 } |
402 return true; | 429 String name = (String)obj2; |
430 int index = stackIndex(name); | |
431 if( index != -1 ) | |
432 return push( new SetLocalVar(index) ); | |
433 index = upValueIndex(name); | |
434 if( index != -1 ) | |
435 return push( new SetUpVar(index) ); | |
436 return push( new SetTableEntry( EnvExpr.INSTANCE, new ConstExpr(name) ) ); | |
403 } | 437 } |
404 | 438 |
405 Rule Expr() { | 439 Rule Expr() { |
406 return FirstOf( | 440 return FirstOf( |
407 VarArgs(), | 441 VarArgs(), |
513 ), | 547 ), |
514 VarArgName() | 548 VarArgName() |
515 ) | 549 ) |
516 ), | 550 ), |
517 ')', decParens(), Spaces(), Block(), Keyword("end"), | 551 ')', decParens(), Spaces(), Block(), Keyword("end"), |
518 push( new Chunk( (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg ) ), | 552 push( newChunk() ), |
519 action( frame = frame.parent ) | 553 action( frame = frame.parent ) |
520 ); | 554 ); |
521 } | 555 } |
522 | 556 |
523 Rule VarArgName() { | 557 Rule VarArgName() { |
615 boolean makeVarExp() { | 649 boolean makeVarExp() { |
616 Object obj2 = pop(); | 650 Object obj2 = pop(); |
617 if( obj2==null ) | 651 if( obj2==null ) |
618 return true; | 652 return true; |
619 Object obj1 = pop(); | 653 Object obj1 = pop(); |
620 if( obj1==null ) { | 654 if( obj1 != null ) |
621 String name = (String)obj2; | 655 return push( new GetExpr( expr(obj1), expr(obj2) ) ); |
622 int index = index(name); | 656 String name = (String)obj2; |
623 if( index == -1 ) { | 657 int index = stackIndex(name); |
624 return push( new GetExpr( EnvExpr.INSTANCE, new ConstExpr(name) ) ); | 658 if( index != -1 ) |
625 } else { | 659 return push( new GetLocalVar(index) ); |
626 return push( new GetLocalVar(index) ); | 660 index = upValueIndex(name); |
627 } | 661 if( index != -1 ) |
628 } | 662 return push( new GetUpVar(index) ); |
629 return push( new GetExpr( expr(obj1), expr(obj2) ) ); | 663 return push( new GetExpr( EnvExpr.INSTANCE, new ConstExpr(name) ) ); |
630 } | 664 } |
631 | 665 |
632 // function should be on top of the stack | 666 // function should be on top of the stack |
633 Rule Args() { | 667 Rule Args() { |
634 return Sequence( | 668 return Sequence( |