diff --git a/grammar.ne b/grammar.ne deleted file mode 100644 index 5e5bd55..0000000 --- a/grammar.ne +++ /dev/null @@ -1,126 +0,0 @@ -@{% -const moo = require('moo'); - -const lexer = moo.compile({ - ws: /[ \t]+/, - nl: { match: /\n/, lineBreaks: true }, - comment: /\/\/.*?$/, - number: /0|[1-9][0-9]*(\.[0-9]+)?/, - string: /"(?:\\["\\]|[^\n"\\])*"/, - lbrace: '{', - rbrace: '}', - lparen: '(', - rparen: ')', - dot: '.', - plus: '+', - comma: ',', - colon: ':', - eq: '=', - identifier: /[a-zA-Z_][a-zA-Z0-9_]*/, -}); -%} - -@lexer lexer - -Program -> _ Statements _ {% ([,,stmts]) => ({ type: 'Program', body: stmts }) %} - -Statements -> Statement (_NL Statement):* _ {% - (d) => { - const stmts = [d[0]]; - for (const rest of d[1]) { - stmts.push(rest[1]); - } - return stmts.filter(s => s !== null && s.type !== 'Comment'); - } -%} - -Statement -> Declaration {% id %} - | Assignment {% id %} - | ExpressionStatement {% id %} - | Comment {% id %} - -ExpressionStatement -> Expression {% (d) => ({ type: 'ExpressionStatement', expression: d[0] }) %} - -Comment -> %comment {% d => ({ type: 'Comment', value: d[0].value }) %} - -Declaration -> %identifier _ %colon _ Expression {% - (d) => ({ - type: 'VariableDeclaration', - identifier: d[0].value, - value: d[4] - }) -%} - -Assignment -> %identifier _ %eq _ Expression {% - (d) => ({ - type: 'Assignment', - identifier: d[0].value, - value: d[4] - }) -%} - -# Expression parsing hierarchy to handle operator precedence -Expression -> Additive {% id %} - -Additive -> Additive _ %plus _ Call {% (d) => ({ type: 'BinaryExpression', operator: '+', left: d[0], right: d[4] }) %} - | Call {% id %} - -Call -> Member ( %lparen _ (ArgumentList):? _ %rparen ):? {% - (d) => { - if (d[1]) { // It is a function call - return { - type: 'CallExpression', - callee: d[0], - arguments: d[1][2] || [] - } - } - return d[0]; // Not a call, just a Member/Primary expression - } -%} - -Member -> Primary ( %dot %identifier ):* {% - (d) => { - let obj = d[0]; - for (const part of d[1]) { - obj = { - type: 'MemberExpression', - object: obj, - property: { type: 'Identifier', name: part[1].value } - } - } - return obj; - } -%} - -Primary -> Literal {% id %} - | Block {% id %} - | Identifier {% id %} - | %lparen _ Expression _ %rparen {% (d) => d[2] %} - -ArgumentList -> Expression ( _ %comma _ Expression):* {% - (d) => [d[0], ...d[1].map(m => m[3])] -%} - -Identifier -> %identifier {% d => ({ type: 'Identifier', name: d[0].value }) %} - -Literal -> %number {% d => ({ type: 'NumericLiteral', value: Number(d[0].value) }) %} - | %string {% d => ({ type: 'StringLiteral', value: d[0].value }) %} - -Block -> %lbrace _ (KeyValuePairs):? _ %rparen {% - (d) => ({ type: 'Block', properties: d[2] || [] }) -%} - -KeyValuePairs -> KeyValuePair (_NL KeyValuePair):* {% - (d) => [d[0], ...d[1].map(m => m[1])] -%} - -KeyValuePair -> %identifier _ %colon _ Expression {% - (d) => ({ - type: 'Property', - key: d[0].value, - value: d[4] - }) -%} - -_ -> (%ws | %comment):* {% () => null %} -_NL -> (_ %nl):+ {% () => null %}