Parse Noir files

pull/5770/head
ioedeveloper 3 weeks ago committed by Aniket
parent 498e11ee73
commit 1bd9907418
  1. 104
      apps/noir-compiler/src/app/services/noirParser.ts
  2. 6
      apps/noir-compiler/src/app/services/noirPluginClient.ts
  3. 2
      package.json
  4. 10
      yarn.lock

@ -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;

@ -6,9 +6,11 @@ import { compile_program, createFileManager } from '@noir-lang/noir_wasm/default
import type { FileManager } from '@noir-lang/noir_wasm/dist/node/main' import type { FileManager } from '@noir-lang/noir_wasm/dist/node/main'
import pathModule from 'path' import pathModule from 'path'
import { DEFAULT_TOML_CONFIG } from '../actions/constants' import { DEFAULT_TOML_CONFIG } from '../actions/constants'
import NoirParser from './noirParser'
export class NoirPluginClient extends PluginClient { export class NoirPluginClient extends PluginClient {
public internalEvents: EventManager public internalEvents: EventManager
public fm: FileManager public fm: FileManager
public parser: NoirParser
constructor() { constructor() {
super() super()
@ -16,6 +18,7 @@ export class NoirPluginClient extends PluginClient {
createClient(this) createClient(this)
this.internalEvents = new EventManager() this.internalEvents = new EventManager()
this.fm = createFileManager('/') this.fm = createFileManager('/')
this.parser = new NoirParser()
this.onload() this.onload()
} }
@ -66,6 +69,9 @@ export class NoirPluginClient extends PluginClient {
async parse(path: string, content?: string): Promise<void> { async parse(path: string, content?: string): Promise<void> {
if (!content) content = await this.call('fileManager', 'readFile', path) if (!content) content = await this.call('fileManager', 'readFile', path)
await this.resolveDependencies(path, content) await this.resolveDependencies(path, content)
const result = this.parser.parseNoirCode(content)
console.log('result: ', result)
const fileBytes = new TextEncoder().encode(content) const fileBytes = new TextEncoder().encode(content)
this.fm.writeFile(`${path}`, new Blob([fileBytes]).stream()) this.fm.writeFile(`${path}`, new Blob([fileBytes]).stream())

@ -142,6 +142,7 @@
"core-js": "^3.6.5", "core-js": "^3.6.5",
"cors": "^2.8.5", "cors": "^2.8.5",
"create-hash": "^1.2.0", "create-hash": "^1.2.0",
"dedent": "^1.5.3",
"deep-equal": "^1.0.1", "deep-equal": "^1.0.1",
"document-register-element": "1.13.1", "document-register-element": "1.13.1",
"electron-squirrel-startup": "^1.0.0", "electron-squirrel-startup": "^1.0.0",
@ -176,6 +177,7 @@
"merge": "^2.1.1", "merge": "^2.1.1",
"npm-install-version": "^6.0.2", "npm-install-version": "^6.0.2",
"octokit": "^3.1.2", "octokit": "^3.1.2",
"ohm-js": "^17.1.0",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"prettier": "^2.8.4", "prettier": "^2.8.4",
"prettier-plugin-solidity": "^1.0.0-beta.24", "prettier-plugin-solidity": "^1.0.0-beta.24",

@ -13536,6 +13536,11 @@ dedent@^0.7.0:
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=
dedent@^1.5.3:
version "1.5.3"
resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a"
integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==
deep-eql@4.0.1: deep-eql@4.0.1:
version "4.0.1" version "4.0.1"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.0.1.tgz#2b65bc89491d193780c452edee2144a91bb0a445" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.0.1.tgz#2b65bc89491d193780c452edee2144a91bb0a445"
@ -24075,6 +24080,11 @@ ofetch@^1.3.3:
node-fetch-native "^1.4.0" node-fetch-native "^1.4.0"
ufo "^1.3.0" ufo "^1.3.0"
ohm-js@^17.1.0:
version "17.1.0"
resolved "https://registry.yarnpkg.com/ohm-js/-/ohm-js-17.1.0.tgz#50d8e08f69d7909931998d75202d35e2a90c8885"
integrity sha512-xc3B5dgAjTBQGHaH7B58M2Pmv6WvzrJ/3/7LeUzXNg0/sY3jQPdSd/S2SstppaleO77rifR1tyhdfFGNIwxf2Q==
on-exit-leak-free@^0.2.0: on-exit-leak-free@^0.2.0:
version "0.2.0" version "0.2.0"
resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209"

Loading…
Cancel
Save