diff --git a/core/src/main/java/org/luaj/vm2/Lua.java b/core/src/main/java/org/luaj/vm2/Lua.java index 4993a76f..a4148b51 100644 --- a/core/src/main/java/org/luaj/vm2/Lua.java +++ b/core/src/main/java/org/luaj/vm2/Lua.java @@ -200,39 +200,40 @@ public class Lua { public static final int OP_SUB = 14; /* A B C R(A) := RK(B) - RK(C) */ public static final int OP_MUL = 15; /* A B C R(A) := RK(B) * RK(C) */ public static final int OP_DIV = 16; /* A B C R(A) := RK(B) / RK(C) */ - public static final int OP_MOD = 17; /* A B C R(A) := RK(B) % RK(C) */ - public static final int OP_POW = 18; /* A B C R(A) := RK(B) ^ RK(C) */ - public static final int OP_UNM = 19; /* A B R(A) := -R(B) */ - public static final int OP_NOT = 20; /* A B R(A) := not R(B) */ - public static final int OP_LEN = 21; /* A B R(A) := length of R(B) */ + public static final int OP_IDIV = 17; /* A B C R(A) := RK(B) // RK(C) */ + public static final int OP_MOD = 18; /* A B C R(A) := RK(B) % RK(C) */ + public static final int OP_POW = 19; /* A B C R(A) := RK(B) ^ RK(C) */ + public static final int OP_UNM = 20; /* A B R(A) := -R(B) */ + public static final int OP_NOT = 21; /* A B R(A) := not R(B) */ + public static final int OP_LEN = 22; /* A B R(A) := length of R(B) */ - public static final int OP_CONCAT = 22; /* A B C R(A) := R(B).. ... ..R(C) */ + public static final int OP_CONCAT = 23; /* A B C R(A) := R(B).. ... ..R(C) */ - public static final int OP_JMP = 23; /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */ - public static final int OP_EQ = 24; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ - public static final int OP_LT = 25; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ - public static final int OP_LE = 26; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ + public static final int OP_JMP = 24; /* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */ + public static final int OP_EQ = 25; /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ + public static final int OP_LT = 26; /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ + public static final int OP_LE = 27; /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ - public static final int OP_TEST = 27; /* A C if not (R(A) <=> C) then pc++ */ - public static final int OP_TESTSET = 28; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + public static final int OP_TEST = 28; /* A C if not (R(A) <=> C) then pc++ */ + public static final int OP_TESTSET = 29; /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ - public static final int OP_CALL = 29; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ - public static final int OP_TAILCALL = 30; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ - public static final int OP_RETURN = 31; /* A B return R(A), ... ,R(A+B-2) (see note) */ + public static final int OP_CALL = 30; /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ + public static final int OP_TAILCALL = 31; /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ + public static final int OP_RETURN = 32; /* A B return R(A), ... ,R(A+B-2) (see note) */ - public static final int OP_FORLOOP = 32; /* A sBx R(A)+=R(A+2); + public static final int OP_FORLOOP = 33; /* A sBx R(A)+=R(A+2); if R(A) >>23)>0xff? k[b&0x0ff]: stack[b]).div((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]); continue; + case Lua.OP_IDIV: /* A B C R(A):= RK(B) // RK(C) */ + stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).idiv((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]); + continue; + case Lua.OP_MOD: /* A B C R(A):= RK(B) % RK(C) */ stack[a] = ((b=i>>>23)>0xff? k[b&0x0ff]: stack[b]).mod((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]); continue; diff --git a/core/src/main/java/org/luaj/vm2/LuaDouble.java b/core/src/main/java/org/luaj/vm2/LuaDouble.java index a0b6f97e..e38daf67 100644 --- a/core/src/main/java/org/luaj/vm2/LuaDouble.java +++ b/core/src/main/java/org/luaj/vm2/LuaDouble.java @@ -139,9 +139,13 @@ public class LuaDouble extends LuaNumber { public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); } public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); } + public LuaValue idiv( LuaValue rhs ) { return rhs.idivInto(v); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); } + public LuaValue idiv( double rhs ) { return LuaDouble.didiv(v,rhs); } + public LuaValue idiv( int rhs ) { return LuaDouble.didiv(v,rhs); } + public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs,v); } public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); } @@ -158,6 +162,10 @@ public class LuaDouble extends LuaNumber { public static LuaValue ddiv(double lhs, double rhs) { return rhs!=0? valueOf( lhs / rhs ): lhs>0? POSINF: lhs==0? NAN: NEGINF; } + + public static LuaValue didiv(double lhs, double rhs) { + return valueOf(Math.floor(ddiv_d(lhs, rhs))); + } /** Divide two double numbers according to lua math, and return a double result. * @param lhs Left-hand-side of the division. diff --git a/core/src/main/java/org/luaj/vm2/LuaInteger.java b/core/src/main/java/org/luaj/vm2/LuaInteger.java index bddff621..36f7e5d9 100644 --- a/core/src/main/java/org/luaj/vm2/LuaInteger.java +++ b/core/src/main/java/org/luaj/vm2/LuaInteger.java @@ -163,9 +163,13 @@ public class LuaInteger extends LuaNumber { public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs,v); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs,v); } public LuaValue div( LuaValue rhs ) { return rhs.divInto(v); } + public LuaValue idiv( LuaValue rhs ) { return rhs.idivInto(v); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(v,rhs); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs,v); } + public LuaValue idiv( double rhs ) { return LuaDouble.didiv(v,rhs); } + public LuaValue idiv( int rhs ) { return LuaDouble.didiv(v,rhs); } + public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs,v); } public LuaValue mod( LuaValue rhs ) { return rhs.modFrom(v); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(v,rhs); } public LuaValue mod( int rhs ) { return LuaDouble.dmod(v,rhs); } diff --git a/core/src/main/java/org/luaj/vm2/LuaString.java b/core/src/main/java/org/luaj/vm2/LuaString.java index db8cc13e..5182993d 100644 --- a/core/src/main/java/org/luaj/vm2/LuaString.java +++ b/core/src/main/java/org/luaj/vm2/LuaString.java @@ -280,9 +280,13 @@ public class LuaString extends LuaValue { public LuaValue powWith( double lhs ) { return MathLib.dpow(lhs, checkarith()); } public LuaValue powWith( int lhs ) { return MathLib.dpow(lhs, checkarith()); } public LuaValue div( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(DIV,rhs): rhs.divInto(d); } + public LuaValue idiv( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(IDIV,rhs): rhs.idivInto(d); } public LuaValue div( double rhs ) { return LuaDouble.ddiv(checkarith(),rhs); } public LuaValue div( int rhs ) { return LuaDouble.ddiv(checkarith(),rhs); } public LuaValue divInto( double lhs ) { return LuaDouble.ddiv(lhs, checkarith()); } + public LuaValue idiv( double rhs ) { return LuaDouble.didiv(checkarith(),rhs); } + public LuaValue idiv( int rhs ) { return LuaDouble.didiv(checkarith(),rhs); } + public LuaValue idivInto( double lhs ) { return LuaDouble.didiv(lhs, checkarith()); } public LuaValue mod( LuaValue rhs ) { double d = scannumber(); return Double.isNaN(d)? arithmt(MOD,rhs): rhs.modFrom(d); } public LuaValue mod( double rhs ) { return LuaDouble.dmod(checkarith(), rhs); } public LuaValue mod( int rhs ) { return LuaDouble.dmod(checkarith(), rhs); } diff --git a/core/src/main/java/org/luaj/vm2/LuaValue.java b/core/src/main/java/org/luaj/vm2/LuaValue.java index c7c287cf..d13b413e 100644 --- a/core/src/main/java/org/luaj/vm2/LuaValue.java +++ b/core/src/main/java/org/luaj/vm2/LuaValue.java @@ -213,6 +213,9 @@ public class LuaValue extends Varargs { /** LuaString constant with value "__div" for use as metatag */ public static final LuaString DIV = valueOf("__div"); + /** LuaString constant with value "__idiv" for use as metatag */ + public static final LuaString IDIV = valueOf("__idiv"); + /** LuaString constant with value "__mul" for use as metatag */ public static final LuaString MUL = valueOf("__mul"); @@ -2398,6 +2401,8 @@ public class LuaValue extends Varargs { * @see #arithmt(LuaValue, LuaValue) */ public LuaValue div( LuaValue rhs ) { return arithmt(DIV,rhs); } + + public LuaValue idiv( LuaValue rhs ) { return arithmt(IDIV,rhs); } /** Divide: Perform numeric divide operation by another value * of double type without metatag processing @@ -2413,6 +2418,8 @@ public class LuaValue extends Varargs { * @see #div(LuaValue) */ public LuaValue div( double rhs ) { return aritherror("div"); } + + public LuaValue idiv( double rhs ) { return aritherror("idiv"); } /** Divide: Perform numeric divide operation by another value * of int type without metatag processing @@ -2428,6 +2435,8 @@ public class LuaValue extends Varargs { * @see #div(LuaValue) */ public LuaValue div( int rhs ) { return aritherror("div"); } + + public LuaValue idiv( int rhs ) { return aritherror("idiv"); } /** Reverse-divide: Perform numeric divide operation into another value * with metatag processing @@ -2443,6 +2452,8 @@ public class LuaValue extends Varargs { * @see #div(int) */ public LuaValue divInto(double lhs) { return arithmtwith(DIV,lhs); } + + public LuaValue idivInto(double lhs) { return arithmtwith(IDIV,lhs); } /** Modulo: Perform numeric modulo operation with another value * of unknown type, diff --git a/core/src/main/java/org/luaj/vm2/Print.java b/core/src/main/java/org/luaj/vm2/Print.java index 8b0bd572..1965658d 100644 --- a/core/src/main/java/org/luaj/vm2/Print.java +++ b/core/src/main/java/org/luaj/vm2/Print.java @@ -276,6 +276,7 @@ public class Print extends Lua { case OP_SUB: case OP_MUL: case OP_DIV: + case OP_IDIV: case OP_POW: case OP_EQ: case OP_LT: diff --git a/core/src/main/java/org/luaj/vm2/compiler/FuncState.java b/core/src/main/java/org/luaj/vm2/compiler/FuncState.java index 4c56a206..b0506963 100644 --- a/core/src/main/java/org/luaj/vm2/compiler/FuncState.java +++ b/core/src/main/java/org/luaj/vm2/compiler/FuncState.java @@ -870,7 +870,7 @@ public class FuncState extends Constants { LuaValue v1, v2, r; if (!e1.isnumeral() || !e2.isnumeral()) return false; - if ((op == OP_DIV || op == OP_MOD) && e2.u.nval().eq_b(LuaValue.ZERO)) + if ((op == OP_DIV || op == OP_IDIV || op == OP_MOD) && e2.u.nval().eq_b(LuaValue.ZERO)) return false; /* do not attempt to divide by 0 */ v1 = e1.u.nval(); v2 = e2.u.nval(); @@ -887,6 +887,9 @@ public class FuncState extends Constants { case OP_DIV: r = v1.div(v2); break; + case OP_IDIV: + r = v1.idiv(v2); + break; case OP_MOD: r = v1.mod(v2); break; @@ -991,6 +994,7 @@ public class FuncState extends Constants { case LexState.OPR_SUB: case LexState.OPR_MUL: case LexState.OPR_DIV: + case LexState.OPR_IDIV: case LexState.OPR_MOD: case LexState.OPR_POW: { if (!v.isnumeral()) @@ -1050,6 +1054,9 @@ public class FuncState extends Constants { case LexState.OPR_DIV: this.codearith(OP_DIV, e1, e2, line); break; + case LexState.OPR_IDIV: + this.codearith(OP_IDIV, e1, e2, line); + break; case LexState.OPR_MOD: this.codearith(OP_MOD, e1, e2, line); break; @@ -1144,4 +1151,4 @@ public class FuncState extends Constants { this.freereg = (short) (base + 1); /* free registers with list values */ } -} \ No newline at end of file +} diff --git a/core/src/main/java/org/luaj/vm2/compiler/LexState.java b/core/src/main/java/org/luaj/vm2/compiler/LexState.java index 94d29c66..3cfa0980 100644 --- a/core/src/main/java/org/luaj/vm2/compiler/LexState.java +++ b/core/src/main/java/org/luaj/vm2/compiler/LexState.java @@ -85,12 +85,12 @@ public class LexState extends Constants { ** grep "ORDER OPR" if you change these enums */ static final int - OPR_ADD=0, OPR_SUB=1, OPR_MUL=2, OPR_DIV=3, OPR_MOD=4, OPR_POW=5, - OPR_CONCAT=6, - OPR_NE=7, OPR_EQ=8, - OPR_LT=9, OPR_LE=10, OPR_GT=11, OPR_GE=12, - OPR_AND=13, OPR_OR=14, - OPR_NOBINOPR=15; + OPR_ADD=0, OPR_SUB=1, OPR_MUL=2, OPR_DIV=3, OPR_IDIV=4, OPR_MOD=5, OPR_POW=6, + OPR_CONCAT=7, + OPR_NE=8, OPR_EQ=9, + OPR_LT=10, OPR_LE=11, OPR_GT=12, OPR_GE=13, + OPR_AND=14, OPR_OR=15, + OPR_NOBINOPR=16; static final int OPR_MINUS=0, OPR_NOT=1, OPR_LEN=2, OPR_NOUNOPR=3; @@ -149,7 +149,7 @@ public class LexState extends Constants { "end", "false", "for", "function", "goto", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", - "..", "...", "==", ">=", "<=", "~=", + "..", "...", "//", "==", ">=", "<=", "~=", "::", "", "", "", "", "", }; @@ -160,8 +160,8 @@ public class LexState extends Constants { TK_IN=268, TK_LOCAL=269, TK_NIL=270, TK_NOT=271, TK_OR=272, TK_REPEAT=273, TK_RETURN=274, TK_THEN=275, TK_TRUE=276, TK_UNTIL=277, TK_WHILE=278, /* other terminal symbols */ - TK_CONCAT=279, TK_DOTS=280, TK_EQ=281, TK_GE=282, TK_LE=283, TK_NE=284, - TK_DBCOLON=285, TK_EOS=286, TK_NUMBER=287, TK_NAME=288, TK_STRING=289; + TK_CONCAT=279, TK_DOTS=280, TK_IDIV=281, TK_EQ=282, TK_GE=283, TK_LE=284, TK_NE=285, + TK_DBCOLON=286, TK_EOS=287, TK_NUMBER=288, TK_NAME=289, TK_STRING=290; final static int FIRST_RESERVED = TK_AND; final static int NUM_RESERVED = TK_WHILE+1-FIRST_RESERVED; @@ -674,6 +674,15 @@ public class LexState extends Constants { return TK_DBCOLON; } } + case '/': { + nextChar(); + if (current != '/') + return '/'; + else { + nextChar(); + return TK_IDIV; + } + } case '"': case '\'': { read_string(current, seminfo); @@ -1517,6 +1526,8 @@ public class LexState extends Constants { return OPR_MUL; case '/': return OPR_DIV; + case TK_IDIV: + return OPR_IDIV; case '%': return OPR_MOD; case '^': @@ -1556,7 +1567,7 @@ public class LexState extends Constants { }; static Priority[] priority = { /* ORDER OPR */ - new Priority(6, 6), new Priority(6, 6), new Priority(7, 7), new Priority(7, 7), new Priority(7, 7), /* `+' `-' `/' `%' */ + new Priority(6, 6), new Priority(6, 6), new Priority(7, 7), new Priority(7, 7), new Priority(7, 7), new Priority(7, 7), /* `+' `-' `*' `/' `//' `%' */ new Priority(10, 9), new Priority(5, 4), /* power and concat (right associative) */ new Priority(3, 3), new Priority(3, 3), /* equality and inequality */ new Priority(3, 3), new Priority(3, 3), new Priority(3, 3), new Priority(3, 3), /* order */ diff --git a/core/src/main/java/org/luaj/vm2/libs/DebugLib.java b/core/src/main/java/org/luaj/vm2/libs/DebugLib.java index 9f07f9af..da6fdb7b 100644 --- a/core/src/main/java/org/luaj/vm2/libs/DebugLib.java +++ b/core/src/main/java/org/luaj/vm2/libs/DebugLib.java @@ -816,6 +816,7 @@ public class DebugLib extends TwoArgFunction { case Lua.OP_SUB: tm = LuaValue.SUB; break; case Lua.OP_MUL: tm = LuaValue.MUL; break; case Lua.OP_DIV: tm = LuaValue.DIV; break; + case Lua.OP_IDIV: tm = LuaValue.IDIV; break; case Lua.OP_MOD: tm = LuaValue.MOD; break; case Lua.OP_POW: tm = LuaValue.POW; break; case Lua.OP_UNM: tm = LuaValue.UNM; break; @@ -951,4 +952,4 @@ public class DebugLib extends TwoArgFunction { } return setreg; } -} \ No newline at end of file +} diff --git a/grammar/Lua52.jj b/grammar/Lua52.jj index d84f4c6f..c5e0c26e 100644 --- a/grammar/Lua52.jj +++ b/grammar/Lua52.jj @@ -353,7 +353,7 @@ void FieldSep(): void Binop(): {} { - "+" | "-" | "*" | "/" | "^" | "%" | ".." | "<" | "<=" | ">" | ">=" | "==" | "~=" | | + "+" | "-" | "*" | "/" | "//" | "^" | "%" | ".." | "<" | "<=" | ">" | ">=" | "==" | "~=" | | } void Unop(): diff --git a/grammar/LuaParser.jj b/grammar/LuaParser.jj index 11c30b8b..2dc3cfa3 100644 --- a/grammar/LuaParser.jj +++ b/grammar/LuaParser.jj @@ -509,6 +509,7 @@ int Binop(): | "-" { return Lua.OP_SUB; } | "*" { return Lua.OP_MUL; } | "/" { return Lua.OP_DIV; } +| "//" { return Lua.OP_IDIV; } | "^" { return Lua.OP_POW; } | "%" { return Lua.OP_MOD; } | ".." { return Lua.OP_CONCAT; } diff --git a/jse/src/main/java/org/luaj/vm2/ast/Exp.java b/jse/src/main/java/org/luaj/vm2/ast/Exp.java index 7b41b60b..ed9afc09 100644 --- a/jse/src/main/java/org/luaj/vm2/ast/Exp.java +++ b/jse/src/main/java/org/luaj/vm2/ast/Exp.java @@ -91,7 +91,7 @@ public class Exp extends SyntaxElement { case Lua.OP_LT: case Lua.OP_GT: case Lua.OP_LE: case Lua.OP_GE: case Lua.OP_NEQ: case Lua.OP_EQ: return 2; case Lua.OP_CONCAT: return 3; case Lua.OP_ADD: case Lua.OP_SUB: return 4; - case Lua.OP_MUL: case Lua.OP_DIV: case Lua.OP_MOD: return 5; + case Lua.OP_MUL: case Lua.OP_DIV: case Lua.OP_IDIV: case Lua.OP_MOD: return 5; case Lua.OP_NOT: case Lua.OP_UNM: case Lua.OP_LEN: return 6; case Lua.OP_POW: return 7; default: throw new IllegalStateException("precedence of bad op "+op); diff --git a/jse/src/main/java/org/luaj/vm2/luajc/JavaBuilder.java b/jse/src/main/java/org/luaj/vm2/luajc/JavaBuilder.java index 52032412..c9df8cff 100644 --- a/jse/src/main/java/org/luaj/vm2/luajc/JavaBuilder.java +++ b/jse/src/main/java/org/luaj/vm2/luajc/JavaBuilder.java @@ -534,6 +534,7 @@ public class JavaBuilder { case Lua.OP_SUB: op = "sub"; break; case Lua.OP_MUL: op = "mul"; break; case Lua.OP_DIV: op = "div"; break; + case Lua.OP_IDIV: op = "idiv"; break; case Lua.OP_MOD: op = "mod"; break; case Lua.OP_POW: op = "pow"; break; } diff --git a/jse/src/main/java/org/luaj/vm2/luajc/JavaGen.java b/jse/src/main/java/org/luaj/vm2/luajc/JavaGen.java index 67a892e3..6fe2d021 100644 --- a/jse/src/main/java/org/luaj/vm2/luajc/JavaGen.java +++ b/jse/src/main/java/org/luaj/vm2/luajc/JavaGen.java @@ -165,6 +165,7 @@ public class JavaGen { case Lua.OP_SUB: /* A B C R(A):= RK(B) - RK(C) */ case Lua.OP_MUL: /* A B C R(A):= RK(B) * RK(C) */ case Lua.OP_DIV: /* A B C R(A):= RK(B) / RK(C) */ + case Lua.OP_IDIV: /* A B C R(A):= RK(B) // RK(C) */ case Lua.OP_MOD: /* A B C R(A):= RK(B) % RK(C) */ case Lua.OP_POW: /* A B C R(A):= RK(B) ^ RK(C) */ loadLocalOrConstant( p, builder, pc, b ); diff --git a/jse/src/main/java/org/luaj/vm2/luajc/ProtoInfo.java b/jse/src/main/java/org/luaj/vm2/luajc/ProtoInfo.java index 0d33f00a..25c9e9f6 100644 --- a/jse/src/main/java/org/luaj/vm2/luajc/ProtoInfo.java +++ b/jse/src/main/java/org/luaj/vm2/luajc/ProtoInfo.java @@ -189,6 +189,7 @@ public class ProtoInfo { case Lua.OP_SUB: /* A B C R(A) := RK(B) - RK(C) */ case Lua.OP_MUL: /* A B C R(A) := RK(B) * RK(C) */ case Lua.OP_DIV: /* A B C R(A) := RK(B) / RK(C) */ + case Lua.OP_IDIV: /* A B C R(A) := RK(B) // RK(C) */ case Lua.OP_MOD: /* A B C R(A) := RK(B) % RK(C) */ case Lua.OP_POW: /* A B C R(A) := RK(B) ^ RK(C) */ a = Lua.GETARG_A( ins ); diff --git a/jse/src/main/java/org/luaj/vm2/parser/LuaParser.java b/jse/src/main/java/org/luaj/vm2/parser/LuaParser.java index c85664f3..1674a1c1 100644 --- a/jse/src/main/java/org/luaj/vm2/parser/LuaParser.java +++ b/jse/src/main/java/org/luaj/vm2/parser/LuaParser.java @@ -960,6 +960,10 @@ public class LuaParser implements LuaParserConstants { final public int Binop() throws ParseException { switch ((jj_ntk==-1)?jj_ntk():jj_ntk) { + case IDIV: + jj_consume_token(IDIV); + {if (true) return Lua.OP_IDIV;} + break; case 82: jj_consume_token(82); {if (true) return Lua.OP_ADD;} diff --git a/jse/src/main/java/org/luaj/vm2/parser/LuaParserConstants.java b/jse/src/main/java/org/luaj/vm2/parser/LuaParserConstants.java index fbab92e7..30c44c29 100644 --- a/jse/src/main/java/org/luaj/vm2/parser/LuaParserConstants.java +++ b/jse/src/main/java/org/luaj/vm2/parser/LuaParserConstants.java @@ -33,6 +33,8 @@ public interface LuaParserConstants { /** RegularExpression Id. */ int LONGSTRINGN = 27; /** RegularExpression Id. */ + int IDIV = 28; + /** RegularExpression Id. */ int AND = 29; /** RegularExpression Id. */ int BREAK = 30; @@ -168,7 +170,7 @@ public interface LuaParserConstants { "\"]==]\"", "\"]===]\"", "", - "", + "\"//\"", "\"and\"", "\"break\"", "\"do\"", diff --git a/jse/src/main/java/org/luaj/vm2/parser/LuaParserTokenManager.java b/jse/src/main/java/org/luaj/vm2/parser/LuaParserTokenManager.java index 3b3dc0c2..ca130b2f 100644 --- a/jse/src/main/java/org/luaj/vm2/parser/LuaParserTokenManager.java +++ b/jse/src/main/java/org/luaj/vm2/parser/LuaParserTokenManager.java @@ -469,7 +469,8 @@ private int jjMoveStringLiteralDfa0_0() jjmatchedKind = 73; return jjMoveStringLiteralDfa1_0(0x0L, 0x1008000L); case 47: - return jjStopAtPos(0, 85); + jjmatchedKind = 85; + return jjMoveStringLiteralDfa1_0(0x0L, 0x1L); case 58: jjmatchedKind = 74; return jjMoveStringLiteralDfa1_0(0x0L, 0x2L); @@ -552,6 +553,10 @@ private int jjMoveStringLiteralDfa1_0(long active0, long active1) jjmatchedPos = 1; } return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x8000L); + case 47: + if ((active1 & 0x1L) != 0L) + return jjStopAtPos(1, 28); + break; case 58: if ((active1 & 0x2L) != 0L) return jjStopAtPos(1, 65); diff --git a/jse/src/test/java/org/luaj/vm2/FragmentsTest.java b/jse/src/test/java/org/luaj/vm2/FragmentsTest.java index bf343ace..12a19bc5 100644 --- a/jse/src/test/java/org/luaj/vm2/FragmentsTest.java +++ b/jse/src/test/java/org/luaj/vm2/FragmentsTest.java @@ -104,6 +104,18 @@ public class FragmentsTest extends TestSuite { "end\n"); } + + public void testFloorDivision() { + runFragment(LuaValue.valueOf(2), "return 5//2\n"); + } + + public void testFloorDivisionNegativeRoundsDown() { + runFragment(LuaValue.valueOf(-3), "return 5//-2\n"); + } + + public void testFloorDivisionInExpression() { + runFragment(LuaValue.TRUE, "local x=5 local width=10 return x==width//2\n"); + } public void testForloopParamUpvalues() { runFragment( LuaValue.varargsOf(new LuaValue[] {