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
8 changes: 7 additions & 1 deletion data_static/expression2/tests/compiler/parser/assign.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@ A--
A += 1
A -= 1
A *= 1
A /= 1
A /= 1
A %= 1
A &&= 1
A ||= 1
A ^^= 1
A >>= 1
A <<= 1
18 changes: 18 additions & 0 deletions data_static/expression2/tests/runtime/types/number/compound.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ assert(X == 8)
X /= 2
assert(X == 4)

X %= 3
assert(X == 1)

X ||= 10
assert(X == 11)

X &&= 8
assert(X == 8)

X ^^= 12
assert(X == 4)

X >>= 2
assert(X == 1)

X <<= 2
assert(X == 4)

X++
assert(X == 5)

Expand Down
3 changes: 3 additions & 0 deletions data_static/expression2/tests/runtime/types/vector4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ assert(vec4(1, 2, 3, 4) + 1 == vec4(2, 3, 4, 5))
assert(vec4(1, 2, 3, 4) - 1 == vec4(0, 1, 2, 3))
assert(vec4(1, 2, 3, 4) * 2 == vec4(2, 4, 6, 8))
assert(vec4(1, 2, 3, 4) / 2 == vec4(0.5, 1, 1.5, 2))
assert(vec4(1, 2, 3, 4) % 2 == vec4(1, 0, 1, 0))

assert(vec4(1, 2, 3, 4) + vec4(1, 1, 1, 1) == vec4(2, 3, 4, 5))
assert(vec4(1, 2, 3, 4) - vec4(1, 1, 1, 1) == vec4(0, 1, 2, 3))
assert(vec4(1, 2, 3, 4) * vec4(2, 2, 2, 2) == vec4(2, 4, 6, 8))
assert(vec4(1, 2, 3, 4) / vec4(2, 2, 2, 2) == vec4(0.5, 1, 1.5, 2))
assert(vec4(1, 2, 3, 4) % vec4(2, 2, 2, 2) == vec4(1, 0, 1, 0))

assert(vec4(1, 2, 3, 4) + vec4(1, 2, 3, 4) == vec4(2, 4, 6, 8))

Expand All @@ -50,5 +52,6 @@ W += 1
W -= 1
W /= 1
W *= 1
W %= 1
W++
W--
18 changes: 16 additions & 2 deletions lua/entities/gmod_wire_expression2/base/compiler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,20 @@ local function empty_array()
return {}
end

---@type table<Operator, NodeVariant>
local CompoundAssignmentVariants = {
[Operator.Add] = NodeVariant.ExprArithmetic,
[Operator.Sub] = NodeVariant.ExprArithmetic,
[Operator.Mul] = NodeVariant.ExprArithmetic,
[Operator.Div] = NodeVariant.ExprArithmetic,
[Operator.Mod] = NodeVariant.ExprArithmetic,
[Operator.Band] = NodeVariant.ExprBinaryOp,
[Operator.Bor] = NodeVariant.ExprBinaryOp,
[Operator.Bxor] = NodeVariant.ExprBinaryOp,
[Operator.Bshr] = NodeVariant.ExprBitShift,
[Operator.Bshl] = NodeVariant.ExprBitShift
}

---@type table<NodeVariant, fun(self: Compiler, trace: Trace, data: table, used_as_stmt: boolean): RuntimeOperator|nil, string?>
local CompileVisitors = {
---@param data Node[]
Expand Down Expand Up @@ -1178,10 +1192,10 @@ local CompileVisitors = {
end,

---@param data { [1]: Token<string>, [2]: Operator, [3]: Node }
[NodeVariant.CompoundArithmetic] = function(self, trace, data)
[NodeVariant.CompoundAssignment] = function(self, trace, data)
-- Transform V <op>= E -> V = V <op> E
local result = Node.new(
NodeVariant.ExprArithmetic,
self:Assert(CompoundAssignmentVariants[data[2]], "Unrecognized compound assignment", trace),
{ Node.new(NodeVariant.ExprIdent, data[1], data[1].trace), data[2], data[3] },
trace
)
Expand Down
46 changes: 41 additions & 5 deletions lua/entities/gmod_wire_expression2/base/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ local NodeVariant = {

Increment = 9, -- `++`
Decrement = 10, -- `--`
CompoundArithmetic = 11, -- `+=`, `-=`, `*=`, `/=`
CompoundAssignment = 11, -- `+=`, `-=`, `*=`, `/=`
Assignment = 12, -- `X = Y[2, number] = Z[2] = 5` or `local X = 5`
Const = 13, -- const X = 5

Expand Down Expand Up @@ -354,13 +354,25 @@ function Parser:Stmt()

--- Compound Assignment
if self:ConsumeValue(TokenVariant.Operator, Operator.Aadd) then
return Node.new(NodeVariant.CompoundArithmetic, { var, Operator.Add, self:Expr() }, var.trace:stitch(self:Prev().trace))
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Add, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Asub) then
return Node.new(NodeVariant.CompoundArithmetic, { var, Operator.Sub, self:Expr() }, var.trace:stitch(self:Prev().trace))
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Sub, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Amul) then
return Node.new(NodeVariant.CompoundArithmetic, { var, Operator.Mul, self:Expr() }, var.trace:stitch(self:Prev().trace))
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Mul, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Adiv) then
return Node.new(NodeVariant.CompoundArithmetic, { var, Operator.Div, self:Expr() }, var.trace:stitch(self:Prev().trace))
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Div, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Amod) then
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Mod, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Aband) then
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Band, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abor) then
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Bor, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abxor) then
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Bxor, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abshr) then
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Bshr, self:Expr() }, var.trace:stitch(self:Prev().trace))
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abshl) then
return Node.new(NodeVariant.CompoundAssignment, { var, Operator.Bshl, self:Expr() }, var.trace:stitch(self:Prev().trace))
end

-- Didn't match anything. Might be something else.
Expand Down Expand Up @@ -694,6 +706,18 @@ function Parser:Expr(ignore_assign)
self:Error("Multiplicative assignment operator (*=) must not be part of equation")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Adiv) then
self:Error("Divisive assignment operator (/=) must not be part of equation")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Amod) then
self:Error("Modular assignment operator (%=) must not be part of equation")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Aband) then
self:Error("Bitwise AND assignment operator (&&=) must not be part of equation")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abor) then
self:Error("Bitwise OR assignment operator (||=) must not be part of equation")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abxor) then
self:Error("Bitwise XOR assignment operator (^^=) must not be part of equation")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abshr) then
self:Error("Right bitwise shift assignment operator (>>=) must not be part of equation")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abshl) then
self:Error("Left bitwise shift assignment operator (<<=) must not be part of equation")
end

self.index = self.index - 1
Expand Down Expand Up @@ -1060,6 +1084,18 @@ function Parser:Expr15()
self:Error("Multiplicative assignment operator (*=) must be preceded by variable")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Adiv) then
self:Error("Divisive assignment operator (/=) must be preceded by variable")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Amod) then
self:Error("Modular assignment operator (%=) must be preceded by variable")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Aband) then
self:Error("Bitwise AND assignment operator (&&=) must be preceded by variable")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abor) then
self:Error("Bitwise OR assignment operator (||=) must be preceded by variable")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abxor) then
self:Error("Bitwise XOR assignment operator (^^=) must be preceded by variable")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abshr) then
self:Error("Right bitwise shift assignment operator (>>=) must be preceded by variable")
elseif self:ConsumeValue(TokenVariant.Operator, Operator.Abshl) then
self:Error("Left bitwise shift assignment operator (<<=) must be preceded by variable")

elseif self:ConsumeValue(TokenVariant.Operator, Operator.And) then
self:Error("Logical and operator (&) must be preceded by equation or value")
Expand Down
12 changes: 12 additions & 0 deletions lua/entities/gmod_wire_expression2/core/angle.lua
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ e2function angle operator/(angle rv1, angle rv2)
return Angle( rv1[1] / rv2[1], rv1[2] / rv2[2], rv1[3] / rv2[3] )
end

e2function angle operator%(rv1, angle rv2)
return Angle( rv1 % rv2[1], rv1 % rv2[2], rv1 % rv2[3] )
end

e2function angle operator%(angle rv1, rv2)
return Angle( rv1[1] % rv2, rv1[2] % rv2, rv1[3] % rv2 )
end

e2function angle operator%(angle rv1, angle rv2)
return Angle( rv1[1] % rv2[1], rv1[2] % rv2[2], rv1[3] % rv2[3] )
end

registerOperator("indexget", "an", "n", function(state, this, index)
return this[floor(math.Clamp(index, 1, 3) + 0.5)]
end)
Expand Down
4 changes: 4 additions & 0 deletions lua/entities/gmod_wire_expression2/core/complex.lua
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ e2function complex operator/(complex lhs, number rhs)
return {lhs[1]/rhs, lhs[2]/rhs}
end

e2function complex operator%(complex lhs, number rhs)
return {lhs[1]%rhs, lhs[2]%rhs}
end

e2function complex operator^(complex lhs, complex rhs)
local l = clog(lhs[1], lhs[2])
local e = {rhs[1]*l[1] - rhs[2]*l[2], rhs[1]*l[2] + rhs[2]*l[1]}
Expand Down
83 changes: 51 additions & 32 deletions lua/entities/gmod_wire_expression2/core/e2lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,12 @@ E2Lib.optable_inv = {
asub = "-=",
amul = "*=",
adiv = "/=",
amod = "%=",
aband = "&&=",
abor = "||=",
abxor = "^^=",
abshr = ">>=",
abshl = "<<=",
inc = "++",
dec = "--",
eq = "==",
Expand Down Expand Up @@ -723,60 +729,72 @@ local Operator = {
Exp = 6,
-- `=`
Ass = 7,
-- +=
-- `+=`
Aadd = 8,
-- -=
-- `-=`
Asub = 9,
-- `*=`
Amul = 10,
-- `/=`
Adiv = 11,
-- `%=`
Amod = 12,
-- ``&&=`
Aband = 13,
-- `||=`
Abor = 14,
-- `^^=`
Abxor = 15,
-- `>>=`
Abshr = 16,
-- `<<=`
Abshl = 17,
-- `++`
Inc = 12,
Inc = 18,
-- `--`
Dec = 13,
Dec = 19,
-- `==`
Eq = 14,
Eq = 20,
-- `!=`
Neq = 15,
Neq = 21,
-- `<`
Lth = 16,
Lth = 22,
-- `>=`
Geq = 17,
Geq = 23,
-- `<=`
Leq = 18,
Leq = 24,
-- `>`
Gth = 19,
Gth = 25,
-- `&&`
Band = 20,
Band = 26,
-- `||`
Bor = 21,
Bor = 27,
-- `^^`
Bxor = 22,
Bxor = 28,
-- `>>`
Bshr = 23,
Bshr = 29,
-- `<<`
Bshl = 24,
Bshl = 30,
-- `!`
Not = 25,
Not = 31,
-- `&`
And = 26,
And = 32,
-- `|`
Or = 27,
Or = 33,
-- `?`
Qsm = 28,
Qsm = 34,
-- `:`
Col = 29,
Col = 35,
-- `?:`
Def = 30,
Def = 36,
-- `$`
Dlt = 31,
Dlt = 37,
-- `~`
Trg = 32,
Trg = 38,
-- `->`
Imp = 33,
Imp = 39,
-- `...`
Spread = 34
Spread = 40
}

E2Lib.Operator = Operator
Expand All @@ -791,13 +809,14 @@ E2Lib.OperatorNames = OperatorNames
local OperatorLookup = {
["+"] = Operator.Add, ["-"] = Operator.Sub, ["*"] = Operator.Mul, ["/"] = Operator.Div,
["%"] = Operator.Mod, ["^"] = Operator.Exp, ["="] = Operator.Ass, ["+="] = Operator.Aadd,
["-="] = Operator.Asub, ["*="] = Operator.Amul, ["/="] = Operator.Adiv, ["++"] = Operator.Inc,
["--"] = Operator.Dec, ["=="] = Operator.Eq, ["!="] = Operator.Neq, ["<"] = Operator.Lth,
[">="] = Operator.Geq, ["<="] = Operator.Leq, [">"] = Operator.Gth, ["&&"] = Operator.Band,
["||"] = Operator.Bor, ["^^"] = Operator.Bxor, [">>"] = Operator.Bshr, ["<<"] = Operator.Bshl,
["!"] = Operator.Not, ["&"] = Operator.And, ["|"] = Operator.Or, ["?"] = Operator.Qsm,
[":"] = Operator.Col, ["?:"] = Operator.Def, ["$"] = Operator.Dlt, ["~"] = Operator.Trg,
["->"] = Operator.Imp, ["..."] = Operator.Spread
["-="] = Operator.Asub, ["*="] = Operator.Amul, ["/="] = Operator.Adiv, ["%="] = Operator.Amod,
["&&="] = Operator.Aband, ["||="] = Operator.Abor, ["^^="] = Operator.Abxor, [">>="] = Operator.Abshr,
["<<="] = Operator.Abshl, ["++"] = Operator.Inc, ["--"] = Operator.Dec, ["=="] = Operator.Eq,
["!="] = Operator.Neq, ["<"] = Operator.Lth, [">="] = Operator.Geq, ["<="] = Operator.Leq,
[">"] = Operator.Gth, ["&&"] = Operator.Band, ["||"] = Operator.Bor, ["^^"] = Operator.Bxor,
[">>"] = Operator.Bshr, ["<<"] = Operator.Bshl, ["!"] = Operator.Not, ["&"] = Operator.And,
["|"] = Operator.Or, ["?"] = Operator.Qsm, [":"] = Operator.Col, ["?:"] = Operator.Def,
["$"] = Operator.Dlt, ["~"] = Operator.Trg, ["->"] = Operator.Imp, ["..."] = Operator.Spread
}

E2Lib.OperatorLookup = OperatorLookup
Expand Down
10 changes: 10 additions & 0 deletions lua/entities/gmod_wire_expression2/core/quaternion.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
Quaternion support
\******************************************************************************/

// TODO: implement more!

Check warning on line 5 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of '--' and '//'

-- faster access to some math library functions

Check warning on line 7 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of '--' and '//'
local abs = math.abs
local Round = math.Round
local sqrt = math.sqrt
Expand All @@ -12,8 +12,8 @@
local log = math.log
local sin = math.sin
local cos = math.cos
local sinh = math.sinh

Check warning on line 15 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Unused variable"

Unused variable: sinh
local cosh = math.cosh

Check warning on line 16 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Unused variable"

Unused variable: cosh
local acos = math.acos

local deg2rad = math.pi/180
Expand Down Expand Up @@ -235,7 +235,7 @@
return {0, 0, 0, 1}
end

--- Returns <n>*k

Check warning on line 238 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of '//' and '--'
e2function quaternion qk(n)
return {0, 0, 0, n}
end
Expand All @@ -245,7 +245,7 @@
__e2setcost(2)

/******************************************************************************/
// TODO: define division as multiplication with (1/x), or is it not useful?

Check warning on line 248 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of '//' and '--'

__e2setcost(4)

Expand Down Expand Up @@ -420,6 +420,16 @@

__e2setcost(4)

e2function quaternion operator%(quaternion lhs, number rhs)
local lhs1, lhs2, lhs3, lhs4 = lhs[1], lhs[2], lhs[3], lhs[4]
return {
lhs1%rhs,
lhs2%rhs,
lhs3%rhs,
lhs4%rhs
}
end

e2function quaternion operator^(number lhs, quaternion rhs)
if lhs == 0 then return { 0, 0, 0, 0 } end
local l = log(lhs)
Expand Down Expand Up @@ -576,7 +586,7 @@
--- Returns vector pointing forward for <this>
e2function vector quaternion:forward()
local this1, this2, this3, this4 = this[1], this[2], this[3], this[4]
local t2, t3, t4 = this2 * 2, this3 * 2, this4 * 2

Check warning on line 589 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Unused variable"

Unused variable: t2
return Vector(
this1 * this1 + this2 * this2 - this3 * this3 - this4 * this4,
t3 * this2 + t4 * this1,
Expand All @@ -598,7 +608,7 @@
--- Returns vector pointing up for <this>
e2function vector quaternion:up()
local this1, this2, this3, this4 = this[1], this[2], this[3], this[4]
local t2, t3, t4 = this2 * 2, this3 * 2, this4 * 2

Check warning on line 611 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Unused variable"

Unused variable: t4
return Vector(
t3 * this1 + t2 * this4,
t3 * this4 - t2 * this1,
Expand Down Expand Up @@ -628,12 +638,12 @@
return { cos(ang2), rv1[1] * sang2len , rv1[2] * sang2len, rv1[3] * sang2len }
end

--- Returns the angle of rotation in degrees (by coder0xff)

Check warning on line 641 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of '//' and '--'
e2function number rotationAngle(quaternion q)
local l2 = q[1]*q[1] + q[2]*q[2] + q[3]*q[3] + q[4]*q[4]
if l2 == 0 then return 0 end
local l = sqrt(l2)
local ang = 2*acos(math.Clamp(q[1]/l, -1, 1))*rad2deg //this returns angle from 0 to 360

Check warning on line 646 in lua/entities/gmod_wire_expression2/core/quaternion.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of '//' and '--'
if ang > 180 then ang = ang - 360 end //make it -180 - 180
return ang
end
Expand Down
12 changes: 12 additions & 0 deletions lua/entities/gmod_wire_expression2/core/vector.lua
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ e2function vector operator/(vector lhs, vector rhs)
return Vector( lhs[1] / rhs[1], lhs[2] / rhs[2], lhs[3] / rhs[3] )
end

e2function vector operator%(lhs, vector rhs)
return Vector( lhs % rhs[1], lhs % rhs[2], lhs % rhs[3] )
end

e2function vector operator%(vector lhs, rhs)
return Vector( lhs[1] % rhs, lhs[2] % rhs, lhs[3] % rhs )
end

e2function vector operator%(vector lhs, vector rhs)
return Vector( lhs[1] % rhs[1], lhs[2] % rhs[2], lhs[3] % rhs[3] )
end

registerOperator("indexget", "vn", "n", function(state, this, index)
return this[floor(math.Clamp(index, 1, 3) + 0.5)]
end)
Expand Down
Loading
Loading