Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/MoonSharp.Interpreter/Execution/InstructionFieldUsage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,20 @@ internal static InstructionFieldUsage GetFieldUsage(this OpCode op)
case OpCode.Sub:
case OpCode.Mul:
case OpCode.Div:
case OpCode.FloorDiv:
case OpCode.Mod:
case OpCode.Not:
case OpCode.Len:
case OpCode.Neg:
case OpCode.Power:
case OpCode.CNot:
case OpCode.ToBool:
case OpCode.BitwiseAnd:
case OpCode.BitwiseOr:
case OpCode.BitwiseXor:
case OpCode.BitwiseLShift:
case OpCode.BitwiseRShift:
case OpCode.BitwiseNot:
return InstructionFieldUsage.None;
case OpCode.Pop:
case OpCode.Copy:
Expand Down
7 changes: 7 additions & 0 deletions src/MoonSharp.Interpreter/Execution/VM/OpCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,19 @@ internal enum OpCode
Sub, // Subtraction of the two topmost operands on the v-stack
Mul, // Multiplication of the two topmost operands on the v-stack
Div, // Division of the two topmost operands on the v-stack
FloorDiv, // Floor Division of the two topmost operands on the v-stack
Mod, // Modulus of the two topmost operands on the v-stack
Not, // Logical inversion of the topmost operand on the v-stack
Len, // Size operator of the topmost operand on the v-stack
Neg, // Negation (unary minus) operator of the topmost operand on the v-stack
Power, // Power of the two topmost operands on the v-stack
CNot, // Conditional NOT - takes second operand from the v-stack (must be bool), if true execs a NOT otherwise execs a TOBOOL
BitwiseAnd, // Bitwise AND of the two topmost operands on the v-stack
BitwiseOr, // Bitwise OR of the two topmost operands on the v-stack
BitwiseXor, // Bitwise XOR of the two topmost operands on the v-stack
BitwiseLShift, // Bitwise Left Shift of the two topmost operands on the v-stack
BitwiseRShift, // Bitwise Right Shift of the two topmost operands on the v-stack
BitwiseNot, // Unary Bitwise NOT of the topmost operand on the v-stack


// Type conversions and manipulations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ private DynValue Processing_Loop(int instructionPtr)
instructionPtr = ExecNeg(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.BitwiseNot:
instructionPtr = ExecBitwiseNot(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.Sub:
instructionPtr = ExecSub(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
Expand All @@ -86,6 +90,10 @@ private DynValue Processing_Loop(int instructionPtr)
instructionPtr = ExecDiv(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.FloorDiv:
instructionPtr = ExecFloorDiv(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.Mod:
instructionPtr = ExecMod(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
Expand All @@ -94,6 +102,26 @@ private DynValue Processing_Loop(int instructionPtr)
instructionPtr = ExecPower(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.BitwiseAnd:
instructionPtr = ExecBitwiseAnd(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.BitwiseOr:
instructionPtr = ExecBitwiseOr(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.BitwiseXor:
instructionPtr = ExecBitwiseXor(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.BitwiseLShift:
instructionPtr = ExecBitwiseLShift(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.BitwiseRShift:
instructionPtr = ExecBitwiseRShift(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
break;
case OpCode.Eq:
instructionPtr = ExecEq(i, instructionPtr);
if (instructionPtr == YIELD_SPECIAL_TRAP) goto yield_to_calling_coroutine;
Expand Down Expand Up @@ -993,6 +1021,28 @@ private int ExecDiv(Instruction i, int instructionPtr)
else throw ScriptRuntimeException.ArithmeticOnNonNumber(l, r);
}
}

private int ExecFloorDiv(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
DynValue l = m_ValueStack.Pop().ToScalar();

double? rn = r.CastToNumber();
double? ln = l.CastToNumber();

if (ln.HasValue && rn.HasValue)
{
m_ValueStack.Push(DynValue.NewNumber(Math.Floor(ln.Value / rn.Value)));
return instructionPtr;
}
else
{
int ip = Internal_InvokeBinaryMetaMethod(l, r, "__idiv", instructionPtr);
if (ip >= 0) return ip;
else throw ScriptRuntimeException.ArithmeticOnNonNumber(l, r);
}
}

private int ExecPower(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
Expand All @@ -1015,6 +1065,126 @@ private int ExecPower(Instruction i, int instructionPtr)

}

private int ExecBitwiseAnd(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
DynValue l = m_ValueStack.Pop().ToScalar();

double? rn = r.CastToNumber();
double? ln = l.CastToNumber();

if (ln.HasValue && rn.HasValue)
{
uint uln = (uint)Math.IEEERemainder(ln.Value, Math.Pow(2.0, 32.0));
uint urn = (uint)Math.IEEERemainder(rn.Value, Math.Pow(2.0, 32.0));

m_ValueStack.Push(DynValue.NewNumber(uln & urn));
return instructionPtr;
}
else
{
int ip = Internal_InvokeBinaryMetaMethod(l, r, "__band", instructionPtr);
if (ip >= 0) return ip;
else throw ScriptRuntimeException.ArithmeticOnNonNumber(l, r);
}
}

private int ExecBitwiseOr(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
DynValue l = m_ValueStack.Pop().ToScalar();

double? rn = r.CastToNumber();
double? ln = l.CastToNumber();

if (ln.HasValue && rn.HasValue)
{
uint uln = (uint)Math.IEEERemainder(ln.Value, Math.Pow(2.0, 32.0));
uint urn = (uint)Math.IEEERemainder(rn.Value, Math.Pow(2.0, 32.0));

m_ValueStack.Push(DynValue.NewNumber(uln | urn));
return instructionPtr;
}
else
{
int ip = Internal_InvokeBinaryMetaMethod(l, r, "__bor", instructionPtr);
if (ip >= 0) return ip;
else throw ScriptRuntimeException.ArithmeticOnNonNumber(l, r);
}
}

private int ExecBitwiseXor(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
DynValue l = m_ValueStack.Pop().ToScalar();

double? rn = r.CastToNumber();
double? ln = l.CastToNumber();

if (ln.HasValue && rn.HasValue)
{
uint uln = (uint)Math.IEEERemainder(ln.Value, Math.Pow(2.0, 32.0));
uint urn = (uint)Math.IEEERemainder(rn.Value, Math.Pow(2.0, 32.0));

m_ValueStack.Push(DynValue.NewNumber(uln ^ urn));
return instructionPtr;
}
else
{
int ip = Internal_InvokeBinaryMetaMethod(l, r, "__bxor", instructionPtr);
if (ip >= 0) return ip;
else throw ScriptRuntimeException.ArithmeticOnNonNumber(l, r);
}
}

private int ExecBitwiseLShift(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
DynValue l = m_ValueStack.Pop().ToScalar();

double? rn = r.CastToNumber();
double? ln = l.CastToNumber();

if (ln.HasValue && rn.HasValue)
{
int iln = (int)Math.IEEERemainder(ln.Value, Math.Pow(2.0, 32.0));
int irn = (int)Math.IEEERemainder(rn.Value, Math.Pow(2.0, 32.0));

m_ValueStack.Push(DynValue.NewNumber(irn < 0 ? iln >> -irn : iln << irn));
return instructionPtr;
}
else
{
int ip = Internal_InvokeBinaryMetaMethod(l, r, "__shl", instructionPtr);
if (ip >= 0) return ip;
else throw ScriptRuntimeException.ArithmeticOnNonNumber(l, r);
}
}

private int ExecBitwiseRShift(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
DynValue l = m_ValueStack.Pop().ToScalar();

double? rn = r.CastToNumber();
double? ln = l.CastToNumber();

if (ln.HasValue && rn.HasValue)
{
int iln = (int)Math.IEEERemainder(ln.Value, Math.Pow(2.0, 32.0));
int irn = (int)Math.IEEERemainder(rn.Value, Math.Pow(2.0, 32.0));

m_ValueStack.Push(DynValue.NewNumber(irn < 0 ? iln << -irn : iln >> irn));
return instructionPtr;
}
else
{
int ip = Internal_InvokeBinaryMetaMethod(l, r, "__shr", instructionPtr);
if (ip >= 0) return ip;
else throw ScriptRuntimeException.ArithmeticOnNonNumber(l, r);
}
}

private int ExecNeg(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
Expand All @@ -1033,6 +1203,25 @@ private int ExecNeg(Instruction i, int instructionPtr)
}
}

private int ExecBitwiseNot(Instruction i, int instructionPtr)
{
DynValue r = m_ValueStack.Pop().ToScalar();
double? rn = r.CastToNumber();

if (rn.HasValue)
{
uint urn = (uint)Math.IEEERemainder(rn.Value, Math.Pow(2.0, 32.0));
m_ValueStack.Push(DynValue.NewNumber(~urn));
return instructionPtr;
}
else
{
int ip = Internal_InvokeUnaryMetaMethod(r, "__bnot", instructionPtr);
if (ip >= 0) return ip;
else throw ScriptRuntimeException.ArithmeticOnNonNumber(r);
}
}


private int ExecEq(Instruction i, int instructionPtr)
{
Expand Down
2 changes: 1 addition & 1 deletion src/MoonSharp.Interpreter/Tree/Expression_.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ internal static Expression SimpleExp(ScriptLoadingContext lcontext)
case TokenType.Function:
lcontext.Lexer.Next();
return new FunctionDefinitionExpression(lcontext, false, false);
case TokenType.Lambda:
case TokenType.Op_BitwiseOr_Or_Lambda:
return new FunctionDefinitionExpression(lcontext, false, true);
default:
return PrimaryExp(lcontext);
Expand Down
Loading