Skip to content

Commit

Permalink
feat: More verbose errors while checking memory values.
Browse files Browse the repository at this point in the history
  • Loading branch information
deleterium committed Mar 1, 2024
1 parent 3b2f520 commit c795933
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 20 deletions.
25 changes: 22 additions & 3 deletions src/__tests__/warnings.a.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,34 @@ describe('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 warnings = "Warning! At line: 1:12. Unused variable 'lb'.\n |long la=0, lb; fixed fa, fb=0.0; fa = fb - (fixed)la;\n | ^"
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 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! At line: 7:21. Unused variable 'foundPlayer'.
| struct PLAYER * foundPlayer;
| ^`
const compiler = new SmartC({ language: 'C', sourceCode: code })
compiler.compile()
expect(compiler.getMachineCode().Warnings).toBe(warnings)
Expand Down
7 changes: 2 additions & 5 deletions src/codeGenerator/codeGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,8 @@ export default function codeGenerator (Program: CONTRACT) {
function checkUnusedVariables () {
Program.memory.forEach(Mem => {
if (Mem.isSet === false) {
if (Mem.scope) {
Program.Context.warnings.push(`Warning! Unused variable '${Mem.name}' in function '${Mem.scope}'.`)
return
}
Program.Context.warnings.push(`Warning! Unused global variable '${Mem.name}'.`)
Program.Context.warnings.push('Warning! ' + Program.Context.formatError(Mem.line,
`Unused variable '${Mem.name}'.`))
}
})
}
Expand Down
2 changes: 2 additions & 0 deletions src/codeGenerator/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default {
asmName: '',
type: 'constant',
scope: '',
line: '0:0',
size: param.length / 16,
declaration: 'long',
isDeclared: true,
Expand All @@ -60,6 +61,7 @@ export default {
asmName: '',
type: 'void',
scope: '',
line: '0:0',
size: 0,
declaration: 'void',
isSet: true,
Expand Down
5 changes: 5 additions & 0 deletions src/shaper/memoryProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export default function memoryProcessor (
header.isDeclared = Program.Context.ShaperContext.isFunctionArgument
header.isSet = Program.Context.ShaperContext.isFunctionArgument
header.toBeRegister = isRegister
header.line = phraseCode[tokenCounter].line
// If is not an array, just send the header
if (dimensions.length === 0) {
return [header]
Expand Down Expand Up @@ -146,6 +147,7 @@ export default function memoryProcessor (
Mem2.name = `${header.name}_${i - 1}`
Mem2.asmName = `${header.asmName}_${i - 1}`
Mem2.scope = Program.Context.ShaperContext.currentScopeName
Mem2.line = phraseCode[tokenCounter].line
Mem2.declaration = header.ArrayItem.declaration
Mem2.isSet = true // No way to track array items for using before initialized
retArrMem.push(Mem2)
Expand Down Expand Up @@ -291,6 +293,7 @@ export default function memoryProcessor (
StructMemHeader.name = phraseCode[startingTokenCounter].value
StructMemHeader.asmName = Program.Context.ShaperContext.currentPrefix + phraseCode[startingTokenCounter].value
StructMemHeader.scope = Program.Context.ShaperContext.currentScopeName
StructMemHeader.line = phraseCode[startingTokenCounter].line
StructMemHeader.isDeclared = Program.Context.ShaperContext.isFunctionArgument
StructMemHeader.isSet = Program.Context.ShaperContext.isFunctionArgument
return [StructMemHeader]
Expand All @@ -309,6 +312,7 @@ export default function memoryProcessor (
StructMemHeader.name = phraseCode[startingTokenCounter].value
StructMemHeader.asmName = Program.Context.ShaperContext.currentPrefix + phraseCode[startingTokenCounter].value
StructMemHeader.scope = Program.Context.ShaperContext.currentScopeName
StructMemHeader.line = phraseCode[startingTokenCounter].line
StructMemHeader.isDeclared = Program.Context.ShaperContext.isFunctionArgument
StructMemHeader.isSet = true // do not control using variables in array
StructMemHeader.type = 'array'
Expand Down Expand Up @@ -371,6 +375,7 @@ export default function memoryProcessor (
Mem.name = variableName + '_' + Mem.name
}
Mem.asmName = Program.Context.ShaperContext.currentPrefix + Mem.name
Mem.line = phraseCode[tokenCounter].line
})
return newmemory
}
Expand Down
20 changes: 8 additions & 12 deletions src/shaper/shaper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ export default function shaper (Program: CONTRACT, tokenAST: TOKEN[]): void {
MemTempl.asmName = Sentence.id
MemTempl.name = Sentence.id
MemTempl.isDeclared = true
MemTempl.line = Sentence.line
Program.memory.push(MemTempl)
}
}
Expand Down Expand Up @@ -436,19 +437,14 @@ export default function shaper (Program: CONTRACT, tokenAST: TOKEN[]): void {
for (i = 0; i < Program.memory.length - 1; i++) {
for (j = i + 1; j < Program.memory.length; j++) {
if (Program.memory[i].asmName === Program.memory[j].asmName) {
if (Program.memory[i].type !== Program.memory[j].type) {
throw new Error('At line: unknown.' +
` Global check: it was found that variable '${Program.memory[i].name}' was declared more` +
` one time with types '${Program.memory[i].type}' and '${Program.memory[j].type}'.`)
if (Program.memory[i].type === 'label' || Program.memory[j].type === 'label') {
throw new Error(Program.Context.formatError(Program.memory[j].line,
`Label '${Program.memory[i].name}' was declared more than one time, ` +
`first declaration at line ${Program.memory[i].line}.` +
'Labels also cannot have same name from variables.'))
}
if (Program.memory[i].type === 'label') {
throw new Error('At line: unknow.' +
` Global check: it was found that label '${Program.memory[i].name}' was` +
' declared more than one time.')
}
throw new Error('At line: unknow.' +
` Global check: it was found that variable '${Program.memory[i].name}' was` +
' declared more than one time.')
throw new Error(Program.Context.formatError(Program.memory[j].line,
`Variable '${Program.memory[i].name}' was first declared at line ${Program.memory[i].line}.`))
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/shaper/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const longArg : MEMORY_SLOT = {
asmName: 'dummy_dummy',
type: 'long',
scope: 'dummy',
line: '0:0',
declaration: 'long',
isSet: false,
toBeRegister: false,
Expand All @@ -80,6 +81,7 @@ const longPtrArg : MEMORY_SLOT = {
asmName: 'dummy_dummy',
type: 'long',
scope: 'dummy',
line: '0:0',
declaration: 'long_ptr',
isSet: false,
toBeRegister: false,
Expand All @@ -93,6 +95,7 @@ const fixedArg : MEMORY_SLOT = {
asmName: 'dummy_dummy',
type: 'fixed',
scope: 'dummy',
line: '0:0',
declaration: 'fixed',
isSet: false,
toBeRegister: false,
Expand All @@ -109,6 +112,7 @@ export const autoCounterTemplate : MEMORY_SLOT = {
isSet: true,
name: '_counterTimestamp',
scope: '',
line: '0:0',
size: 1,
type: 'long'
}
Expand Down Expand Up @@ -150,6 +154,7 @@ export const BuiltInTemplate: SC_FUNCTION[] = [
asmName: 'memcopy_addr1',
type: 'long',
scope: 'memcopy',
line: '0:0',
declaration: 'void_ptr',
isSet: false,
toBeRegister: false,
Expand All @@ -162,6 +167,7 @@ export const BuiltInTemplate: SC_FUNCTION[] = [
asmName: 'memcopy_addr2',
type: 'long',
scope: 'memcopy',
line: '0:0',
declaration: 'void_ptr',
isSet: false,
toBeRegister: false,
Expand Down Expand Up @@ -632,6 +638,7 @@ export function getMemoryTemplate (memType: MEMORY_BASE_TYPES) : MEMORY_SLOT {
address: -1,
name: '',
scope: '',
line: '0:0',
size: -1
}
}
Expand All @@ -646,6 +653,7 @@ export const fixedBaseTemplate : MEMORY_SLOT = {
name: 'f100000000',
hexContent: '0000000005f5e100',
scope: '',
line: '0:0',
size: 1,
type: 'fixed'
}
Expand Down
2 changes: 2 additions & 0 deletions src/typings/syntaxTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ export type MEMORY_SLOT = {
name: string
/** Variable scope */
scope: string
/** Line of declaration */
line: string
/** Variable size in longs */
size: number
/** struct type definition OR array type definition */
Expand Down

0 comments on commit c795933

Please sign in to comment.