Skip to content

Commit

Permalink
Feat: Waning unused variables
Browse files Browse the repository at this point in the history
  • Loading branch information
deleterium committed Feb 18, 2024
1 parent a5351e5 commit ce0bc8d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 15 deletions.
16 changes: 8 additions & 8 deletions src/__tests__/misc.a.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,17 @@ describe('Wrong code to check error safeguards', () => {

describe('Warnings', () => {
it('should compile with warning: right side of operator', () => {
const code = 'long la=0, lb; fixed fa, fb=0.0; fa = fb - la;'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare lb\n^declare fa\n^declare fb\n\nCLR @la\nCLR @fb\nSET @fa $fb\nSET @r0 $la\nMUL @r0 $f100000000\nSUB @fa $r0\nFIN\n'
const code = 'long la=0 ; fixed fa, fb=0.0; fa = fb - la;'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare fa\n^declare fb\n\nCLR @la\nCLR @fb\nSET @fa $fb\nSET @r0 $la\nMUL @r0 $f100000000\nSUB @fa $r0\nFIN\n'
const warnings = "Warning: at line 1:42. Implicit type casting conversion on right side of operator '-'."
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
expect(compiler.getAssemblyCode()).toBe(assembly)
expect(compiler.getMachineCode().Warnings).toBe(warnings)
})
it('should compile with warning: left side of operator', () => {
const code = 'long la=2, lb; fixed fa, fb=0.0; fa = la - fb;\n#pragma optimizationLevel 0'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare lb\n^declare fa\n^declare fb\n\nSET @la #0000000000000002\nCLR @fb\nSET @fa $la\nMUL @fa $f100000000\nSUB @fa $fb\nFIN\n'
const code = 'long la=2 ; fixed fa, fb=0.0; fa = la - fb;\n#pragma optimizationLevel 0'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare fa\n^declare fb\n\nSET @la #0000000000000002\nCLR @fb\nSET @fa $la\nMUL @fa $f100000000\nSUB @fa $fb\nFIN\n'
const warnings = "Warning: at line 1:42. Implicit type casting conversion on left side of operator '-'."
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
Expand All @@ -240,17 +240,17 @@ describe('Warnings', () => {
expect(compiler.getMachineCode().Warnings).toBe(warnings)
})
it('should compile with warning: left side of comparision', () => {
const code = 'long la=1, lb; fixed fa, fb=1.1; if(la < fb) la++;\n#pragma optimizationLevel 0\n'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare lb\n^declare fa\n^declare fb\n\nSET @la #0000000000000001\nSET @fb #00000000068e7780\nSET @r0 $la\nMUL @r0 $f100000000\nBGE $r0 $fb :__if1_endif\n__if1_start:\nINC @la\n__if1_endif:\nFIN\n'
const code = 'long la=1 ; fixed fb=1.1; if(la < fb) la++;\n#pragma optimizationLevel 0\n'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare fb\n\nSET @la #0000000000000001\nSET @fb #00000000068e7780\nSET @r0 $la\nMUL @r0 $f100000000\nBGE $r0 $fb :__if1_endif\n__if1_start:\nINC @la\n__if1_endif:\nFIN\n'
const warnings = "Warning: at line 1:40. Implicit type casting conversion on left side of comparision '<'."
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
expect(compiler.getAssemblyCode()).toBe(assembly)
expect(compiler.getMachineCode().Warnings).toBe(warnings)
})
it('should compile with warning: right side of assignment', () => {
const code = 'long la, lb; fixed fa, fb=0.0; la = fb;'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare lb\n^declare fa\n^declare fb\n\nCLR @fb\nSET @la $fb\nDIV @la $f100000000\nFIN\n'
const code = 'long la ; fixed fb=0.0; la = fb;'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare fb\n\nCLR @fb\nSET @la $fb\nDIV @la $f100000000\nFIN\n'
const warnings = "Warning: at line 1:35. Implicit type casting conversion on right side of assignment '='."
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
Expand Down
22 changes: 19 additions & 3 deletions src/__tests__/warnings.a.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,40 @@ import { SmartC } from '../smartc'

describe('Warnings', () => {
it('should not warn: add or sub pointers with longs values (struct_ptr)', () => {
const code = 'search(2);\nstruct PLAYER { long address, balance, VDLS; } *playerPtr, players[2];\nstruct PLAYER * search(long playerAddress) {\nlong nPlayers=0;\n struct PLAYER * foundPlayer;\n foundPlayer = &players[0];\n for (long auxI = 0; auxI < nPlayers; auxI++) {\n if (foundPlayer->address == playerAddress) {\n return foundPlayer;\n }\n foundPlayer += (sizeof(struct PLAYER));\n foundPlayer = foundPlayer + (sizeof(struct PLAYER));\n foundPlayer++;\n }\n return NULL;\n}'
const code = 'search(2);\nstruct PLAYER { long address, balance, VDLS; } players[2];\nstruct PLAYER * search(long playerAddress) {\nlong nPlayers=0;\n struct PLAYER * foundPlayer;\n foundPlayer = &players[0];\n for (long auxI = 0; auxI < nPlayers; auxI++) {\n if (foundPlayer->address == playerAddress) {\n return foundPlayer;\n }\n foundPlayer += (sizeof(struct PLAYER));\n foundPlayer = foundPlayer + (sizeof(struct PLAYER));\n foundPlayer++;\n }\n return NULL;\n}'
const warnings = ''
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
expect(compiler.getMachineCode().Warnings).toBe(warnings)
})
it('should warn: longs used before initialization', () => {
const code = 'struct PLAYER { long sa, sb; } player;\nlong a, b;\nlong message[4];\n\na+=1;\na = message[b];\na = player.sb;\n'
const code = 'struct PLAYER { long sb; } player;\nlong a, b;\nlong message[4];\n\na+=1;\na = message[b];\na = player.sb;\n'
const warnings = "Warning: at line 5:1. Variable 'a' is used but not initialized.\nWarning: at line 6:13. Variable 'b' is used but not initialized.\nWarning: at line 7:12. Variable 'player_sb' is used but not initialized."
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
expect(compiler.getMachineCode().Warnings).toBe(warnings)
})
it('should not warn: same as before but initialized', () => {
const code = 'struct PLAYER { long sa, sb; } player;\nlong a, b;\nlong message[4];\n\na=b=1;\na = message[b];\nplayer.sb=message[2];\na = player.sb;\n'
const code = 'struct PLAYER { long sb; } player;\nlong a, b;\nlong message[4];\n\na=b=1;\na = message[b];\nplayer.sb=message[2];\na = player.sb;\n'
const warnings = ''
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
expect(compiler.getMachineCode().Warnings).toBe(warnings)
})
it('should compile with warning: unused global variable', () => {
const code = 'long la=0, lb; fixed fa, fb=0.0; fa = fb - (fixed)la;'
const assembly = '^declare r0\n^declare r1\n^declare r2\n^declare f100000000\n^const SET @f100000000 #0000000005f5e100\n^declare la\n^declare lb\n^declare fa\n^declare fb\n\nCLR @la\nCLR @fb\nSET @r0 $la\nMUL @r0 $f100000000\nSET @fa $fb\nSUB @fa $r0\nFIN\n'
const warnings = "Warning: Unused global variable 'lb'."
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
expect(compiler.getAssemblyCode()).toBe(assembly)
expect(compiler.getMachineCode().Warnings).toBe(warnings)
})
it('should warn: Variable not used inside a function', () => {
const code = 'search(2); struct PLAYER { long address, balance, VDLS; } *playerPtr, players[2]; struct PLAYER * search(long playerAddress) { long nPlayers=0; struct PLAYER * foundPlayer; playerPtr = &players[0]; for (long auxI = 0; auxI < nPlayers; auxI++) { if (playerPtr->address == playerAddress) { return playerPtr; } playerPtr += (sizeof(struct PLAYER)); playerPtr = playerPtr + (sizeof(struct PLAYER)); playerPtr++; } return NULL;}'
const warnings = "Warning: Unused variable 'foundPlayer' in function 'search'."
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
expect(compiler.getMachineCode().Warnings).toBe(warnings)
})
})
13 changes: 13 additions & 0 deletions src/codeGenerator/codeGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export default function codeGenerator (Program: CONTRACT) {
'Inline cannot be used in recursive functions neither have circular dependency of each other.')
}
}
checkUnusedVariables()
// Inspect if there were errros and throw now
if (GlobalCodeVars.errors.length !== 0) {
throw new Error(GlobalCodeVars.errors + Program.warnings)
Expand Down Expand Up @@ -252,6 +253,18 @@ export default function codeGenerator (Program: CONTRACT) {
}
}

function checkUnusedVariables () {
Program.memory.forEach(Mem => {
if (Mem.isSet === false) {
if (Mem.scope) {
Program.warnings.push(`Warning: Unused variable '${Mem.name}' in function '${Mem.scope}'.`)
return
}
Program.warnings.push(`Warning: Unused global variable '${Mem.name}'.`)
}
})
}

/** Hot stuff!!! Assemble sentences!! */
function compileSentence (Sentence: SENTENCES) {
let sentenceID: string
Expand Down
12 changes: 8 additions & 4 deletions src/shaper/memoryProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export default function memoryProcessor (
throw new Error(`At line: ${startingLine}.` +
` Could not find type definition for 'struct' '${currentStructNameDef}'.`)
}
return createMemoryObjectFromSTD(currentStructNameDef, phraseCode[tokenCounter].value, isStructPointer)
return createMemoryObjectFromSTD(currentStructNameDef, phraseCode[tokenCounter].value, isStructPointer, false)
}
// isStructPointer is true
if (StructTD === undefined) {
Expand Down Expand Up @@ -308,7 +308,7 @@ export default function memoryProcessor (
StructMemHeader.asmName = AuxVars.currentPrefix + phraseCode[startingTokenCounter].value
StructMemHeader.scope = AuxVars.currentScopeName
StructMemHeader.isDeclared = AuxVars.isFunctionArgument
StructMemHeader.isSet = AuxVars.isFunctionArgument
StructMemHeader.isSet = true // do not control using variables in array
StructMemHeader.type = 'array'
StructMemHeader.typeDefinition = StructMemHeader.asmName
StructMemHeader.ArrayItem = {
Expand All @@ -326,7 +326,8 @@ export default function memoryProcessor (
retStructMemory.push(...createMemoryObjectFromSTD(
currentStructNameDef,
phraseCode[tokenCounter - structArrDimensions.length].value + '_' + ((i - 1) / StructMemHeader.size).toString(),
isStructPointer
isStructPointer,
true
))
}
// create array type definition
Expand All @@ -350,7 +351,7 @@ export default function memoryProcessor (
/** Create an array of memory objects from a given structTypeName.
* The memory objects will be named variableName. */
function createMemoryObjectFromSTD (
structTypeName: string, variableName: string, ispointer: boolean
structTypeName: string, variableName: string, ispointer: boolean, isArray: boolean
) : MEMORY_SLOT[] {
const StructTD = assertNotUndefined(findSTD(structTypeName),
'Internal error.')
Expand All @@ -359,6 +360,9 @@ export default function memoryProcessor (
newmemory.push(...deepCopy(StructTD.structMembers))
}
newmemory.forEach(Mem => {
if (isArray) {
Mem.isSet = true
}
if (Mem.name === '') {
Mem.name = variableName
} else {
Expand Down

0 comments on commit ce0bc8d

Please sign in to comment.