parent
498e11ee73
commit
1bd9907418
@ -0,0 +1,104 @@ |
|||||||
|
// Noir Circuit Program Parser
|
||||||
|
// Detects syntax errors and warnings in .nr files
|
||||||
|
|
||||||
|
class NoirParser { |
||||||
|
errors: any; |
||||||
|
currentLine: any; |
||||||
|
currentColumn: number; |
||||||
|
constructor() { |
||||||
|
this.errors = []; |
||||||
|
this.currentLine = 1; |
||||||
|
this.currentColumn = 1; |
||||||
|
} |
||||||
|
|
||||||
|
parseNoirCode(code) { |
||||||
|
this.errors = []; |
||||||
|
this.currentLine = 1; |
||||||
|
this.currentColumn = 1; |
||||||
|
|
||||||
|
const lines = code.split('\n'); |
||||||
|
let inFunctionBody = false; |
||||||
|
|
||||||
|
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) { |
||||||
|
const line = lines[lineIdx].trim(); |
||||||
|
|
||||||
|
// Skip empty lines or comments
|
||||||
|
if (line === '' || line.startsWith('//')) { |
||||||
|
this.currentLine++; |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
// Track function body
|
||||||
|
if (line.includes('{')) { |
||||||
|
inFunctionBody = true; |
||||||
|
} else if (line.includes('}')) { |
||||||
|
inFunctionBody = false; |
||||||
|
} |
||||||
|
|
||||||
|
// Check for multiple semicolons
|
||||||
|
const semicolonMatches = [...line.matchAll(/;/g)]; |
||||||
|
if (semicolonMatches.length > 1) { |
||||||
|
this.addError( |
||||||
|
'Multiple semicolons in a single statement', |
||||||
|
lineIdx + 1, |
||||||
|
semicolonMatches[1].index + 1, |
||||||
|
[lineIdx + 1, line.length] |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// Check module imports
|
||||||
|
if (line.startsWith('mod ')) { |
||||||
|
const modulePattern = /^mod\s+[a-zA-Z_][a-zA-Z0-9_]*\s*;?$/; |
||||||
|
if (!modulePattern.test(line)) { |
||||||
|
this.addError( |
||||||
|
'Invalid module import syntax', |
||||||
|
lineIdx + 1, |
||||||
|
1, |
||||||
|
[lineIdx + 1, line.length] |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Check statement semicolons
|
||||||
|
if (inFunctionBody && |
||||||
|
!line.endsWith('{') && |
||||||
|
!line.endsWith('}') && |
||||||
|
!line.startsWith('fn ') && |
||||||
|
!line.startsWith('//') && |
||||||
|
!line.endsWith(';') && |
||||||
|
line.length > 0) { |
||||||
|
this.addError( |
||||||
|
'Missing semicolon at statement end', |
||||||
|
lineIdx + 1, |
||||||
|
line.length, |
||||||
|
[lineIdx + 1, line.length] |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
// Check for trailing whitespace
|
||||||
|
if (lines[lineIdx].endsWith(' ')) { |
||||||
|
this.addError( |
||||||
|
'Trailing whitespace', |
||||||
|
lineIdx + 1, |
||||||
|
lines[lineIdx].length, |
||||||
|
[lineIdx + 1, lines[lineIdx].length] |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
this.currentLine++; |
||||||
|
} |
||||||
|
|
||||||
|
return this.errors; |
||||||
|
} |
||||||
|
|
||||||
|
addError(message, line, column, range) { |
||||||
|
this.errors.push({ |
||||||
|
message, |
||||||
|
line, |
||||||
|
column, |
||||||
|
range: range || [line, column] |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default NoirParser; |
Loading…
Reference in new issue