Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structs can now pass into and be returned from functions + Easy struct reassignment #17

Merged
merged 3 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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: 6 additions & 1 deletion lua/wire/client/hlzasm/hc_codetree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,12 @@ function HCOMP:GenerateLeaf(leaf,needResult)

-- Make register operand temporary if requested
if genOperands[i].ForceTemporary then
local initReg = genOperands[i].Register
local initReg
if genOperands[i].Register then
initReg = genOperands[i].Register
elseif genOperands[i].MemoryRegister then
initReg = genOperands[i].MemoryRegister
end
genOperands[i].ForceTemporary = false

if self.RegisterBusy[initReg] then
Expand Down
3 changes: 2 additions & 1 deletion lua/wire/client/hlzasm/hc_compiler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ function HCOMP:StartCompile(sourceCode,fileName,writeByteCallback,writeByteCalle

-- All functions defined so far
self.Functions = {}

-- Details about the current function that we're building
self.CurFunction = {}
-- All macros defined so far
self.Defines = {}
self.Defines["__LINE__"] = 0
Expand Down
115 changes: 108 additions & 7 deletions lua/wire/client/hlzasm/hc_expression.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,33 @@ function HCOMP:Expression_FunctionCall(label) local TOKEN = self.TOKEN

-- Push arguments to stack in reverse order
for argNo = #argumentExpression,1,-1 do
local pushLeaf = self:NewLeaf()
pushLeaf.Opcode = "push"
pushLeaf.Operands[1] = argumentExpression[argNo]
table.insert(genLeaves,pushLeaf)
local pushLeaf
if argumentExpression[argNo].Memory then
if argumentExpression[argNo].Memory.CopySize then
for i=argumentExpression[argNo].Memory.CopySize-1,0,-1 do
pushLeaf = self:NewLeaf()
pushLeaf.Comment = " passing large variable, byte "..i
pushLeaf.Opcode = "push"
local a = argumentExpression[argNo]
local copiedArg = {
CurrentPosition = argumentExpression[argNo].CurrentPosition,
Memory = a.Memory,
MemAddrOffset = i
}
-- Memory will update globally when it receives the final value
-- so we wrap it into a new copy of the table with a constant num
-- because setting the const in memory would update the same table multiple times
pushLeaf.Operands[1] = copiedArg
table.insert(genLeaves,pushLeaf)
end
argumentCount = argumentCount + argumentExpression[argNo].Memory.CopySize-1
end
else
pushLeaf = self:NewLeaf()
pushLeaf.Opcode = "push"
pushLeaf.Operands[1] = argumentExpression[argNo]
table.insert(genLeaves,pushLeaf)
end

if functionEntry then
if functionEntry.Parameters[argNo] then
Expand Down Expand Up @@ -145,6 +168,18 @@ function HCOMP:Expression_FunctionCall(label) local TOKEN = self.TOKEN
end

-- Return EAX as the return value
if self.Functions[label] then
if self.StructSize[self.Functions[label].ReturnType] then
-- Return as memory register that requests copy of x size
return { MemoryRegister = 1, ForceTemporary = true, CopySize = self.StructSize[self.Functions[label].ReturnType], PreviousLeaf = genLeaves[#genLeaves]}
end
elseif self.CurFunction then
if self.CurFunction.ReturnType then
if self.StructSize[self.CurFunction.ReturnType] then
return { MemoryRegister = 1, ForceTemporary = true, CopySize = self.StructSize[self.CurFunction.ReturnType], PreviousLeaf = genLeaves[#genLeaves]}
end
end
end
return { Register = 1, ForceTemporary = true, PreviousLeaf = genLeaves[#genLeaves] }
end

Expand Down Expand Up @@ -332,7 +367,7 @@ function HCOMP:Expression_Level3() local TOKEN = self.TOKEN
addressLeaf.Operands[2] = { Constant = structData[memberName].Offset }
operationLeaf = { MemoryPointer = addressLeaf }
else
operationLeaf = { Stack = structLabel.StackOffset+structData[memberName].Offset }
operationLeaf = { Stack = structLabel.StackOffset+structData[memberName].Offset-1 }
end
elseif structLabel.Type == "Variable" then
if structLabel.PointerToStruct then
Expand Down Expand Up @@ -373,7 +408,12 @@ function HCOMP:Expression_Level3() local TOKEN = self.TOKEN
else -- Parse variable access
if label.Type == "Variable" then -- Read from a variable
-- Array variables are resolved as pointers at constant expression stage
operationLeaf = { Memory = label, ForceType = forceType }
if label.Struct then
operationLeaf = { Memory = label, ForceType = forceType }
operationLeaf.Memory.CopySize = self.StructSize[label.Struct]
else
operationLeaf = { Memory = label, ForceType = forceType }
end
elseif label.Type == "Unknown" then -- Read from an unknown variable
operationLeaf = { UnknownOperationByLabel = label, ForceType = forceType }
elseif label.Type == "Stack" then -- Read from stack
Expand Down Expand Up @@ -485,7 +525,68 @@ function HCOMP:Expression_Level0()

if self:MatchToken(self.TOKEN.EQUAL) then -- =
local rightLeaf = self:Expression_LevelLeaf(0)

if leftLeaf.Memory then
if rightLeaf.Memory then
if leftLeaf.Memory.CopySize and rightLeaf.Memory.CopySize then
local topLeaf = self:NewOpcode("mov",leftLeaf,rightLeaf)
local curLeaf = topLeaf
local tempLeftLeaf,tempRightLeaf
for i=1,math.min(leftLeaf.Memory.CopySize,rightLeaf.Memory.CopySize)-1 do
tempLeftLeaf = {
CurrentPosition = leftLeaf.CurrentPosition,
Memory = leftLeaf.Memory,
MemAddrOffset = i
}
tempRightLeaf = {
CurrentPosition = rightLeaf.CurrentPosition,
Memory = rightLeaf.Memory,
MemAddrOffset = i
}
curLeaf.PreviousLeaf = self:NewOpcode("mov",tempLeftLeaf,tempRightLeaf)
curLeaf = curLeaf.PreviousLeaf
end
-- example of generated output (because previousleaf is parsed before the leaf containing previousleaf)
-- MOV #0+2,#3+2
-- MOV #0+1,#3+1
-- MOV #0,#3
-- * Mark these both with an offset so they won't warn
leftLeaf.MemAddrOffset = 0
rightLeaf.MemAddrOffset = 0
curLeaf.Comment = topLeaf.Comment
topLeaf.Comment = nil
return topLeaf
end
elseif rightLeaf.MemoryRegister then
if leftLeaf.Memory.CopySize and rightLeaf.CopySize then
local topLeaf = self:NewOpcode("mov",leftLeaf,rightLeaf)
local curLeaf = topLeaf
local tempLeftLeaf
for i=1,math.min(leftLeaf.Memory.CopySize,rightLeaf.CopySize)-1 do
tempLeftLeaf = {
CurrentPosition = leftLeaf.CurrentPosition,
Memory = leftLeaf.Memory,
MemAddrOffset = i
}
curLeaf.PreviousLeaf = self:NewOpcode("inc",{Register = rightLeaf.MemoryRegister})
curLeaf = curLeaf.PreviousLeaf
curLeaf.PreviousLeaf = self:NewOpcode("mov",tempLeftLeaf,rightLeaf)
curLeaf = curLeaf.PreviousLeaf
end
-- example of generated output (because previousleaf is parsed before the leaf containing previousleaf)
-- MOV #0+2,#R0
-- INC R0
-- MOV #0+1,#R0
-- INC R0
-- MOV #0,#R0
-- * Mark these both with an offset so they won't warn
leftLeaf.MemAddrOffset = 0
rightLeaf.MemAddrOffset = 0
curLeaf.Comment = topLeaf.Comment
topLeaf.Comment = nil
return topLeaf
end
end
end
-- Mark this leaf as an explict assign operation
local operationLeaf = self:NewOpcode("mov",leftLeaf,rightLeaf)
operationLeaf.ExplictAssign = true
Expand Down
27 changes: 25 additions & 2 deletions lua/wire/client/hlzasm/hc_output.lua
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,28 @@ function HCOMP:PrintBlock(block,file,isLibrary)
printText = printText .. "#" .. block.Operands[i].MemoryPointer
end
elseif block.Operands[i].Memory then
if not block.Operands[i].MemAddrOffset then
if block.Operands[i].Memory.CopySize then
if block.Operands[1].Memory and i ~= 1 then
if block.Operands[i].Memory.CopySize then
self:Warning("Operation will only use first byte of large variables on left and right, use &varname to get a pointer instead")
end
else
if not block.Operands[i].MemAddrOffset then
PrintTable(block.Operands[i])
self:Warning("Operation will only use first byte of large variable on right, use &varname to get a pointer instead")
end
end
end
end
if istable(block.Operands[i].Memory) then
if block.Operands[i].Memory.Value
then printText = printText .. "#" .. block.Operands[i].Memory.Value
then
if block.Operands[i].MemAddrOffset then
printText = printText .. "#" .. block.Operands[i].Memory.Value + block.Operands[i].MemAddrOffset
else
printText = printText .. "#" .. block.Operands[i].Memory.Value
end
else printText = printText .. "#" .. block.Operands[i].Memory.Name
end
else
Expand Down Expand Up @@ -530,7 +549,11 @@ function HCOMP:OperandRM(operand,block)
end
elseif operand.Memory then
if istable(operand.Memory) then -- label
operand.Value = operand.Memory.Value
if operand.MemAddrOffset then
operand.Value = operand.Memory.Value + operand.MemAddrOffset
else
operand.Value = operand.Memory.Value
end
else -- constant
operand.Value = operand.Memory
end
Expand Down
43 changes: 38 additions & 5 deletions lua/wire/client/hlzasm/hc_syntax.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
COLOR = { {"x","r"},{"y","g"},{"z","b"},{"w","a"} },
MATRIX = {},
}
for i=0,15 do VectorSyntax.MATRIX[i+1] = {tostring(i)} end

Check warning on line 24 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator

Check warning on line 24 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator



Expand All @@ -35,10 +35,10 @@

-- Check if opcode is obsolete or old
if self.OpcodeObsolete[opcodeName] then
self:Warning("Instruction \""..opcodeName.."\" is obsolete")

Check warning on line 38 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator

Check warning on line 38 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator
end
if self.OpcodeOld[opcodeName] then
self:Warning("Mnemonic \""..opcodeName.."\" is an old mnemonic for this instruction. Please use the newer mnemonic \""..self.OpcodeOld[opcodeName].."\".")

Check warning on line 41 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator

Check warning on line 41 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator

Check warning on line 41 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator

Check warning on line 41 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator
end

-- Create leaf
Expand All @@ -47,7 +47,7 @@
opcodeLeaf.ExplictAssign = true

-- Parse operands
for i=1,operandCount do

Check warning on line 50 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Whitespace style"

Style: Please put some whitespace before the operator
local segmentOffset,constantValue,expressionLeaf
local isMemoryReference,useSpecialMemorySyntax

Expand Down Expand Up @@ -81,7 +81,7 @@

-- Check if it's a memory reference (#<...>)
if not useSpecialMemorySyntax then
if self:MatchToken(TOKEN.HASH) then isMemoryReference = true end

Check warning on line 84 in lua/wire/client/hlzasm/hc_syntax.lua

View workflow job for this annotation

GitHub Actions / lint

"Double if-statement"

Double if statement. Please combine the condition of this if statement with that of the outer if statement using `and`.
end

-- Parse operand expression (use previous result if previous const wasnt related to seg offset)
Expand Down Expand Up @@ -513,7 +513,15 @@
-- Create function entrypoint
local label
label = self:DefineLabel(varName)

self:PreviousToken() -- LPAREN
self:PreviousToken() -- Func Name
self:PreviousToken() -- Type Name
self:MatchToken(TOKEN.IDENT) -- Type Name
local returnType = self.TokenData
self:MatchToken(TOKEN.IDENT)
local funcName = self.TokenData
self.CurFunction = {Name = funcName, ReturnType = returnType}
self:NextToken()
label.Type = "Pointer"
label.Defined = true

Expand Down Expand Up @@ -1134,12 +1142,37 @@
if self:MatchToken(TOKEN.RETURN) and self.HeadLeaf then
if not self:MatchToken(TOKEN.COLON) then
local returnExpression = self:Expression()
local copyLargeVariable = false
if self.StructSize[self.CurFunction.ReturnType] then
copyLargeVariable = true -- Converts this to automatically return ptr to large variable
end
local returnLeaf = self:NewLeaf()
returnLeaf.Opcode = "mov"
returnLeaf.Operands[1] = { Register = 1 }
returnLeaf.Operands[2] = returnExpression
returnLeaf.ExplictAssign = true
local preReturnLeaf,postReturnLeaf
if copyLargeVariable then
local finalReturnExpression = returnExpression
returnLeaf.Opcode = "mov"
returnLeaf.Operands[1] = { Register = 1 }
if returnExpression.Stack then
finalReturnExpression = { Register = 8 } -- EBP, the stack frame register, where the stack ptr is local to
postReturnLeaf = self:NewOpcode("add",returnLeaf.Operands[1],{Constant = returnExpression.Stack})
-- MOV EAX,EBP
-- ADD EAX,(stack-pos)
end
returnLeaf.Operands[2] = finalReturnExpression
returnLeaf.ExplictAssign = true
else
returnLeaf.Opcode = "mov"
returnLeaf.Operands[1] = { Register = 1 }
returnLeaf.Operands[2] = returnExpression
returnLeaf.ExplictAssign = true
end
if preReturnLeaf then
self:AddLeafToTail(preReturnLeaf)
end
self:AddLeafToTail(returnLeaf)
if postReturnLeaf then
self:AddLeafToTail(postReturnLeaf)
end
end
self:MatchToken(TOKEN.COLON)

Expand Down
Loading