Mercurial Hosting > luan
changeset 7:bca8fc5d928b
work on expressions
git-svn-id: https://luan-java.googlecode.com/svn/trunk@8 21e917c8-12df-6dd8-5cb6-c86387c605b9
author | fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9> |
---|---|
date | Tue, 20 Nov 2012 10:06:27 +0000 |
parents | a315783c9524 |
children | 8896068e0a4b |
files | src/luan/Lua.java src/luan/interp/AndExpr.java src/luan/interp/DivExpr.java src/luan/interp/EqExpr.java src/luan/interp/LenExpr.java src/luan/interp/LengthExpr.java src/luan/interp/LuaParser.java src/luan/interp/ModExpr.java src/luan/interp/MulExpr.java src/luan/interp/NotExpr.java src/luan/interp/OrExpr.java src/luan/interp/UnmExpr.java |
diffstat | 12 files changed, 313 insertions(+), 78 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/Lua.java Mon Nov 19 13:08:30 2012 +0000 +++ b/src/luan/Lua.java Tue Nov 20 10:06:27 2012 +0000 @@ -15,6 +15,10 @@ return "userdata"; } + public static boolean toBoolean(Object obj) { + return obj != null && !Boolean.FALSE.equals(obj); + } + public static String toString(Object obj) { if( obj == null ) return "nil";
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/AndExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,18 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaException; +import luan.LuaState; + + +final class AndExpr extends BinaryOpExpr { + + AndExpr(Expr op1,Expr op2) { + super(op1,op2); + } + + @Override Object eval(LuaState lua) throws LuaException { + Object v1 = op1.eval(lua); + return !Lua.toBoolean(v1) ? v1 : op2.eval(lua); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/DivExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,20 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaNumber; +import luan.LuaException; +import luan.LuaState; + + +final class DivExpr extends BinaryOpExpr { + + DivExpr(Expr op1,Expr op2) { + super(op1,op2); + } + + @Override Object eval(LuaState lua) throws LuaException { + double n1 = Lua.checkNumber(op1.eval(lua)).value(); + double n2 = Lua.checkNumber(op2.eval(lua)).value(); + return new LuaNumber( n1 / n2 ); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/EqExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,20 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaNumber; +import luan.LuaException; +import luan.LuaState; + + +final class EqExpr extends BinaryOpExpr { + + EqExpr(Expr op1,Expr op2) { + super(op1,op2); + } + + @Override Object eval(LuaState lua) throws LuaException { + Object v1 = op1.eval(lua); + Object v2 = op2.eval(lua); + return v1 == v2 || v1 != null && v1.equals(v2); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/LenExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,31 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaNumber; +import luan.LuaTable; +import luan.LuaException; +import luan.LuaState; + + +final class LenExpr extends UnaryOpExpr { + + LenExpr(Expr op) { + super(op); + } + + @Override Object eval(LuaState lua) throws LuaException { + return new LuaNumber( length(op.eval(lua)) ); + } + + private static int length(Object obj) throws LuaException { + if( obj instanceof String ) { + String s = (String)obj; + return s.length(); + } + if( obj instanceof LuaTable ) { + LuaTable t = (LuaTable)obj; + return t.length(); + } + throw new LuaException( "attempt to get length of a " + Lua.type(obj) + " value" ); + } +}
--- a/src/luan/interp/LengthExpr.java Mon Nov 19 13:08:30 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -package luan.interp; - -import luan.Lua; -import luan.LuaNumber; -import luan.LuaTable; -import luan.LuaException; -import luan.LuaState; - - -final class LengthExpr extends UnaryOpExpr { - - LengthExpr(Expr op) { - super(op); - } - - @Override Object eval(LuaState lua) throws LuaException { - return new LuaNumber( length(op.eval(lua)) ); - } - - private static int length(Object obj) throws LuaException { - if( obj instanceof String ) { - String s = (String)obj; - return s.length(); - } - if( obj instanceof LuaTable ) { - LuaTable t = (LuaTable)obj; - return t.length(); - } - throw new LuaException( "attempt to get length of a " + Lua.type(obj) + " value" ); - } -}
--- a/src/luan/interp/LuaParser.java Mon Nov 19 13:08:30 2012 +0000 +++ b/src/luan/interp/LuaParser.java Tue Nov 20 10:06:27 2012 +0000 @@ -15,46 +15,108 @@ public class LuaParser extends BaseParser<Object> { Rule Target() { - return Sequence(ConstExpr(), EOI); + return Sequence(Spaces(), Expr(), EOI); + } + + Rule Expr() { + return OrExpr(); + } + + Rule OrExpr() { + return Sequence( + AndExpr(), + ZeroOrMore( "or", Spaces(), AndExpr(), push( new OrExpr((Expr)pop(1),(Expr)pop()) ) ) + ); + } + + Rule AndExpr() { + return Sequence( + RelExpr(), + ZeroOrMore( "and", Spaces(), RelExpr(), push( new AndExpr((Expr)pop(1),(Expr)pop()) ) ) + ); + } + + Rule RelExpr() { + return Sequence( + SumExpr(), + ZeroOrMore( + FirstOf( + Sequence( "==", Spaces(), SumExpr(), push( new EqExpr((Expr)pop(1),(Expr)pop()) ) ), + Sequence( "~=", Spaces(), SumExpr(), push( new NotExpr(new EqExpr((Expr)pop(1),(Expr)pop())) ) ) + ) + ) + ); } - Rule ConstExpr() { + Rule SumExpr() { + return Sequence( + TermExpr(), + ZeroOrMore( + FirstOf( + Sequence( '+', Spaces(), TermExpr(), push( new AddExpr((Expr)pop(1),(Expr)pop()) ) ), + Sequence( '-', Spaces(), TermExpr(), push( new SubExpr((Expr)pop(1),(Expr)pop()) ) ) + ) + ) + ); + } + + Rule TermExpr() { return Sequence( - Const(), + UnaryExpr(), + ZeroOrMore( + FirstOf( + Sequence( '*', Spaces(), UnaryExpr(), push( new MulExpr((Expr)pop(1),(Expr)pop()) ) ), + Sequence( '/', Spaces(), UnaryExpr(), push( new DivExpr((Expr)pop(1),(Expr)pop()) ) ), + Sequence( '%', Spaces(), UnaryExpr(), push( new ModExpr((Expr)pop(1),(Expr)pop()) ) ) + ) + ) + ); + } + + Rule UnaryExpr() { + return FirstOf( + Sequence( '#', Spaces(), SingleExpr(), push( new LenExpr((Expr)pop()) ) ), + Sequence( '-', Spaces(), SingleExpr(), push( new UnmExpr((Expr)pop()) ) ), + Sequence( "not", Spaces(), SingleExpr(), push( new NotExpr((Expr)pop()) ) ), + SingleExpr() + ); + } + + Rule SingleExpr() { + return FirstOf( + Sequence( '(', Spaces(), Expr(), ')', Spaces() ), + LiteralExpr() + ); + } + + Rule LiteralExpr() { + return Sequence( + Literal(), Spaces(), push(new ConstExpr(pop())) ); } - Rule Const() { + Rule Literal() { return FirstOf( - NilConst(), - BooleanConst(), - NumberConst(), - StringConst() + NilLiteral(), + BooleanLiteral(), + NumberLiteral(), + StringLiteral() ); } - Rule NilConst() { - return Sequence( - String("nil"), - push(null) + Rule NilLiteral() { + return Sequence( "nil", push(null) ); + } + + Rule BooleanLiteral() { + return FirstOf( + Sequence( "true", push(true) ), + Sequence( "false", push(false) ) ); } - Rule BooleanConst() { - return FirstOf( - Sequence( - String("true"), - push(true) - ), - Sequence( - String("false"), - push(false) - ) - ); - } - - Rule NumberConst() { + Rule NumberLiteral() { return Sequence( Number(), push(new LuaNumber((Double)pop())) @@ -79,17 +141,10 @@ return FirstOf( Sequence( Int(), - Optional( - Ch('.'), - Optional(Int()) - ), + Optional( '.', Optional(Int()) ), NumberExp() ), - Sequence( - Ch('.'), - Int(), - NumberExp() - ) + Sequence( '.', Int(), NumberExp() ) ); } @@ -116,7 +171,7 @@ return CharRange('0', '9'); } - Rule StringConst() { + Rule StringLiteral() { return FirstOf( QuotedString('"'), QuotedString('\'') @@ -125,7 +180,7 @@ Rule QuotedString(char quote) { return Sequence( - Ch(quote), + quote, push(new StringBuffer()), ZeroOrMore( FirstOf( @@ -136,23 +191,42 @@ EscSeq() ) ), - Ch(quote), + quote, push(((StringBuffer)pop()).toString()) ); } Rule EscSeq() { return Sequence( - Ch('\\'), + '\\', FirstOf( - Sequence( Ch('b'), append('\b') ), - Sequence( Ch('f'), append('\f') ), - Sequence( Ch('n'), append('\n') ), - Sequence( Ch('r'), append('\r') ), - Sequence( Ch('t'), append('\t') ), - Sequence( Ch('\\'), append('\\') ), - Sequence( Ch('"'), append('"') ), - Sequence( Ch('\''), append('\'') ) + Sequence( 'a', append('\u0007') ), + Sequence( 'b', append('\b') ), + Sequence( 'f', append('\f') ), + Sequence( 'n', append('\n') ), + Sequence( 'r', append('\r') ), + Sequence( 't', append('\t') ), + Sequence( 'v', append('\u000b') ), + Sequence( '\\', append('\\') ), + Sequence( '"', append('"') ), + Sequence( '\'', append('\'') ), + Sequence( + 'x', + Sequence( HexDigit(), HexDigit() ), + append( (char)Integer.parseInt(match(),16) ) + ), + Sequence( + Sequence( + Digit(), + Optional( + Digit(), + Optional( + Digit() + ) + ) + ), + append( (char)Integer.parseInt(match()) ) + ) ) ); } @@ -163,6 +237,10 @@ return true; } + public Rule Spaces() { + return ZeroOrMore(AnyOf(" \t")); + } + // for testing public static void main(String[] args) throws Exception { LuaParser parser = Parboiled.createParser(LuaParser.class);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/ModExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,20 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaNumber; +import luan.LuaException; +import luan.LuaState; + + +final class ModExpr extends BinaryOpExpr { + + ModExpr(Expr op1,Expr op2) { + super(op1,op2); + } + + @Override Object eval(LuaState lua) throws LuaException { + double n1 = Lua.checkNumber(op1.eval(lua)).value(); + double n2 = Lua.checkNumber(op2.eval(lua)).value(); + return new LuaNumber( n1 % n2 ); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/MulExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,20 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaNumber; +import luan.LuaException; +import luan.LuaState; + + +final class MulExpr extends BinaryOpExpr { + + MulExpr(Expr op1,Expr op2) { + super(op1,op2); + } + + @Override Object eval(LuaState lua) throws LuaException { + double n1 = Lua.checkNumber(op1.eval(lua)).value(); + double n2 = Lua.checkNumber(op2.eval(lua)).value(); + return new LuaNumber( n1 * n2 ); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/NotExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,17 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaException; +import luan.LuaState; + + +final class NotExpr extends UnaryOpExpr { + + NotExpr(Expr op) { + super(op); + } + + @Override Object eval(LuaState lua) throws LuaException { + return !Lua.toBoolean(op.eval(lua)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/OrExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,18 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaException; +import luan.LuaState; + + +final class OrExpr extends BinaryOpExpr { + + OrExpr(Expr op1,Expr op2) { + super(op1,op2); + } + + @Override Object eval(LuaState lua) throws LuaException { + Object v1 = op1.eval(lua); + return Lua.toBoolean(v1) ? v1 : op2.eval(lua); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/interp/UnmExpr.java Tue Nov 20 10:06:27 2012 +0000 @@ -0,0 +1,20 @@ +package luan.interp; + +import luan.Lua; +import luan.LuaNumber; +import luan.LuaException; +import luan.LuaState; + + +// unary minus +final class UnmExpr extends UnaryOpExpr { + + UnmExpr(Expr op) { + super(op); + } + + @Override Object eval(LuaState lua) throws LuaException { + double n = Lua.checkNumber(op.eval(lua)).value(); + return new LuaNumber( -n ); + } +}