Mercurial Hosting > luan
changeset 24:7ee247560db5
add VarArgs
git-svn-id: https://luan-java.googlecode.com/svn/trunk@25 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Thu, 06 Dec 2012 04:40:54 +0000 |
parents | 2446c1755d9b |
children | 0e406bd9ac7b |
files | src/luan/LuaClosure.java src/luan/LuaState.java src/luan/interp/Chunk.java src/luan/interp/LuaParser.java src/luan/interp/VarArgs.java |
diffstat | 5 files changed, 67 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
diff -r 2446c1755d9b -r 7ee247560db5 src/luan/LuaClosure.java --- a/src/luan/LuaClosure.java Thu Dec 06 00:35:13 2012 +0000 +++ b/src/luan/LuaClosure.java Thu Dec 06 04:40:54 2012 +0000 @@ -14,7 +14,18 @@ public Object[] call(LuaState lua,Object... args) throws LuaException { Chunk chunk = this.chunk; while(true) { - Object[] stack = lua.newStack(chunk.stackSize); + Object[] varArgs = null; + if( chunk.isVarArg ) { + if( args.length > chunk.numArgs ) { + varArgs = new Object[ args.length - chunk.numArgs ]; + for( int i=0; i<varArgs.length; i++ ) { + varArgs[i] = args[chunk.numArgs+i]; + } + } else { + varArgs = LuaFunction.EMPTY_RTN; + } + } + Object[] stack = lua.newStack(chunk.stackSize,varArgs); final int n = Math.min(args.length,chunk.numArgs); for( int i=0; i<n; i++ ) { stack[i] = args[i];
diff -r 2446c1755d9b -r 7ee247560db5 src/luan/LuaState.java --- a/src/luan/LuaState.java Thu Dec 06 00:35:13 2012 +0000 +++ b/src/luan/LuaState.java Thu Dec 06 04:40:54 2012 +0000 @@ -12,10 +12,12 @@ private static class LuaStack { final LuaStack previousStack; final Object[] a; + final Object[] varArgs; - LuaStack( LuaStack previousStack, int stackSize) { + LuaStack( LuaStack previousStack, int stackSize, Object[] varArgs) { this.previousStack = previousStack; this.a = new Object[stackSize]; + this.varArgs = varArgs; } } @@ -23,8 +25,8 @@ public Object[] returnValues; public LuaClosure tailFn; - Object[] newStack(int stackSize) { - stack = new LuaStack(stack,stackSize); + Object[] newStack(int stackSize, Object[] varArgs) { + stack = new LuaStack(stack,stackSize,varArgs); return stack.a; } @@ -38,4 +40,7 @@ return stack.a; } + public Object[] varArgs() { + return stack.varArgs; + } }
diff -r 2446c1755d9b -r 7ee247560db5 src/luan/interp/Chunk.java --- a/src/luan/interp/Chunk.java Thu Dec 06 00:35:13 2012 +0000 +++ b/src/luan/interp/Chunk.java Thu Dec 06 04:40:54 2012 +0000 @@ -9,11 +9,13 @@ public final Stmt block; public final int stackSize; public final int numArgs; + public final boolean isVarArg; - Chunk(Stmt block,int stackSize,int numArgs) { + Chunk(Stmt block,int stackSize,int numArgs,boolean isVarArg) { this.block = block; this.stackSize = stackSize; this.numArgs = numArgs; + this.isVarArg = isVarArg; fixReturns(block); }
diff -r 2446c1755d9b -r 7ee247560db5 src/luan/interp/LuaParser.java --- a/src/luan/interp/LuaParser.java Thu Dec 06 00:35:13 2012 +0000 +++ b/src/luan/interp/LuaParser.java Thu Dec 06 04:40:54 2012 +0000 @@ -28,6 +28,7 @@ final List<String> symbols = new ArrayList<String>(); int stackSize = 0; int loops = 0; + boolean isVarArg = false; Frame(Frame parent) { this.parent = parent; @@ -105,7 +106,7 @@ Sequence( Block(), EOI, - push( new Chunk( (Stmt)pop(), frame.stackSize, 0 ) ) + push( new Chunk( (Stmt)pop(), frame.stackSize, 0, false ) ) ) ) ); @@ -391,7 +392,10 @@ } Rule Expr() { - return OrExpr(); + return FirstOf( + VarArgs(), + OrExpr() + ); } Rule OrExpr() { @@ -488,12 +492,34 @@ Rule Function() { return Sequence( action( frame = new Frame(frame) ), - '(', incParens(), Spaces(), Optional(NameList()), ')', decParens(), Spaces(), Block(), Keyword("end"), - push( new Chunk( (Stmt)pop(), frame.stackSize, symbolsSize() ) ), + '(', incParens(), Spaces(), + Optional( + FirstOf( + Sequence( NameList(), Optional( ',', Spaces(), VarArgName() ) ), + VarArgName() + ) + ), + ')', decParens(), Spaces(), Block(), Keyword("end"), + push( new Chunk( (Stmt)pop(), frame.stackSize, symbolsSize(), frame.isVarArg ) ), action( frame = frame.parent ) ); } + Rule VarArgName() { + return Sequence( + "...", Spaces(), + action( frame.isVarArg = true ) + ); + } + + Rule VarArgs() { + return Sequence( + "...", Spaces(), + frame.isVarArg, + push( VarArgs.INSTANCE ) + ); + } + Rule TableExpr() { return Sequence( '{', incParens(), Spaces(),
diff -r 2446c1755d9b -r 7ee247560db5 src/luan/interp/VarArgs.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/VarArgs.java Thu Dec 06 04:40:54 2012 +0000 @@ -0,0 +1,14 @@ +package luan.interp; + +import luan.LuaState; + + +final class VarArgs implements Expressions { + static final VarArgs INSTANCE = new VarArgs(); + + private VarArgs() {} + + @Override public Object[] eval(LuaState lua) { + return lua.varArgs(); + } +}