Initial commit
parent
2335e1740c
commit
a9e16640ca
@ -1,5 +1,2 @@
|
|||||||
# https://git-scm.com/docs/gitignore
|
|
||||||
# https://help.github.com/articles/ignoring-files
|
|
||||||
# Example .gitignore files: https://github.com/github/gitignore
|
|
||||||
/bower_components/
|
|
||||||
/node_modules/
|
/node_modules/
|
||||||
|
/lib/
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
/node_modules/
|
@ -0,0 +1,29 @@
|
|||||||
|
# nix-parser
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[WTFPL](http://www.wtfpl.net/txt/copying/) or [CC0](https://creativecommons.org/publicdomain/zero/1.0/), whichever you prefer. A donation and/or attribution are appreciated, but not required.
|
||||||
|
|
||||||
|
## Donate
|
||||||
|
|
||||||
|
My income consists largely of donations for my projects. If this module is useful to you, consider [making a donation](http://cryto.net/~joepie91/donate.html)!
|
||||||
|
|
||||||
|
You can donate using Bitcoin, PayPal, Flattr, cash-in-mail, SEPA transfers, and pretty much anything else.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Pull requests welcome. Please make sure your modifications are in line with the overall code style, and ensure that you're editing the files in `src/`, not those in `lib/`.
|
||||||
|
|
||||||
|
Build tool of choice is `gulp`; simply run `gulp` while developing, and it will watch for changes.
|
||||||
|
|
||||||
|
Be aware that by making a pull request, you agree to release your modifications under the licenses stated above.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
TODO
|
@ -0,0 +1,31 @@
|
|||||||
|
var gulp = require("gulp");
|
||||||
|
var presetES2015 = require("@joepie91/gulp-preset-es2015");
|
||||||
|
var presetPegjs = require("@joepie91/gulp-preset-pegjs");
|
||||||
|
|
||||||
|
var sources = {
|
||||||
|
babel: ["src/**/*.js"],
|
||||||
|
pegjs: ["src/**/*.pegjs"]
|
||||||
|
}
|
||||||
|
|
||||||
|
gulp.task('babel', function() {
|
||||||
|
return gulp.src(sources.babel)
|
||||||
|
.pipe(presetES2015({
|
||||||
|
basePath: __dirname
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest("lib/"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task('pegjs', function() {
|
||||||
|
return gulp.src(sources.pegjs)
|
||||||
|
.pipe(presetPegjs({
|
||||||
|
basePath: __dirname
|
||||||
|
}))
|
||||||
|
.pipe(gulp.dest("lib/"));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("watch", function () {
|
||||||
|
gulp.watch(sources.babel, ["babel"]);
|
||||||
|
gulp.watch(sources.pegjs, ["pegjs"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("default", ["babel", "pegjs", "watch"]);
|
@ -0,0 +1,3 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = require("./lib");
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "nix-parser",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Parser for Nix expressions",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "http://git.cryto.net/joepie91/node-nix-parser.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"nix",
|
||||||
|
"parser",
|
||||||
|
"nixos"
|
||||||
|
],
|
||||||
|
"author": "Sven Slootweg",
|
||||||
|
"license": "WTFPL",
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"@joepie91/gulp-preset-es2015": "^1.0.1",
|
||||||
|
"@joepie91/gulp-preset-pegjs": "^1.0.0",
|
||||||
|
"babel-preset-es2015": "^6.6.0",
|
||||||
|
"gulp": "^3.9.1"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
{
|
||||||
|
function concatRepeat(first, rest, restIndex) {
|
||||||
|
return [first].concat(rest.map(function(item) {
|
||||||
|
return item[restIndex];
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function unnestFunctionCalls(first, nested, last) {
|
||||||
|
var callStack = nested.concat([last]);
|
||||||
|
|
||||||
|
function createFunctionCall(i) {
|
||||||
|
var func;
|
||||||
|
|
||||||
|
if (i === 0) {
|
||||||
|
func = first;
|
||||||
|
} else {
|
||||||
|
func = createFunctionCall(i - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "functionCall",
|
||||||
|
argument: callStack[i],
|
||||||
|
function: func
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return createFunctionCall(callStack.length - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start
|
||||||
|
= _ expression:expression* _ { return expression; }
|
||||||
|
|
||||||
|
// Character classes
|
||||||
|
whitespace
|
||||||
|
= "\t"
|
||||||
|
/ "\n"
|
||||||
|
/ "\r"
|
||||||
|
/ " "
|
||||||
|
|
||||||
|
stringLiteralCharacter
|
||||||
|
= !('"' / "\\") char:. { return char; }
|
||||||
|
/ "\\" escapableCharacter
|
||||||
|
|
||||||
|
numberLiteralCharacter
|
||||||
|
= [0-9.]
|
||||||
|
|
||||||
|
escapableCharacter
|
||||||
|
= '"'
|
||||||
|
/ "n"
|
||||||
|
/ "t"
|
||||||
|
/ "r"
|
||||||
|
|
||||||
|
commentCharacter
|
||||||
|
= [^\n\r]
|
||||||
|
|
||||||
|
// Literals
|
||||||
|
stringLiteral
|
||||||
|
= '"' chars:stringLiteralCharacter+ '"' { return {type: "stringLiteral", value: chars.join("")} }
|
||||||
|
|
||||||
|
numberLiteral
|
||||||
|
= chars:numberLiteralCharacter+ { return {type: "numberLiteral", value: chars.join("")} }
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
_
|
||||||
|
= (whitespace / comment)* {}
|
||||||
|
|
||||||
|
// Language constructs
|
||||||
|
expression
|
||||||
|
= additive
|
||||||
|
/ operand
|
||||||
|
|
||||||
|
comment
|
||||||
|
= "#" chars:commentCharacter* _ { return {type: "comment", text: chars.join("")} }
|
||||||
|
|
||||||
|
operand
|
||||||
|
= group
|
||||||
|
/ letBlock
|
||||||
|
/ stringLiteral
|
||||||
|
/ numberLiteral
|
||||||
|
/ functionDefinition
|
||||||
|
/ recursiveSet
|
||||||
|
/ set
|
||||||
|
/ possiblyNestedFunctionCall
|
||||||
|
/ identifier
|
||||||
|
|
||||||
|
additive
|
||||||
|
= left:subtractive
|
||||||
|
_ "+"
|
||||||
|
_ right:additive { return {type: "operation", operator: "+", left: left, right: right} }
|
||||||
|
/ subtractive
|
||||||
|
|
||||||
|
subtractive
|
||||||
|
= left:multiplicative
|
||||||
|
_ "-"
|
||||||
|
_ right:subtractive { return {type: "operation", operator: "-", left: left, right: right} }
|
||||||
|
/ multiplicative
|
||||||
|
|
||||||
|
multiplicative
|
||||||
|
= left:operand
|
||||||
|
_ "*"
|
||||||
|
_ right:multiplicative { return {type: "operation", operator: "*", left: left, right: right} }
|
||||||
|
/ operand
|
||||||
|
|
||||||
|
identifier
|
||||||
|
= literal:stringLiteral { return {type: "identifier", identifier: literal.value} }
|
||||||
|
/ chars:[a-z.]i+ { return {type: "identifier", identifier: text()} }
|
||||||
|
|
||||||
|
group
|
||||||
|
= "("
|
||||||
|
_ expression:expression
|
||||||
|
_ ")" { return {type: "group", expression: expression} }
|
||||||
|
|
||||||
|
functionDefinition
|
||||||
|
= argument:functionDefinitionArgument
|
||||||
|
_ ":"
|
||||||
|
_ body:expression { return {type: "functionDefinition", argument: argument, body: body} }
|
||||||
|
|
||||||
|
functionDefinitionArgument
|
||||||
|
= identifier
|
||||||
|
/ setPattern
|
||||||
|
|
||||||
|
//functionCallWithParens
|
||||||
|
// = functionName:expression "("
|
||||||
|
// _ arg:expression
|
||||||
|
// _ ")" {return {type: "functionCall", name: functionName, argument: arg} }
|
||||||
|
//
|
||||||
|
//functionCallWithoutParens
|
||||||
|
// = functionName:expression " "
|
||||||
|
// _ arg:expression {return {type: "functionCall", name: functionName, argument: arg} }
|
||||||
|
//
|
||||||
|
//functionCall
|
||||||
|
// = functionCallWithParens
|
||||||
|
// / functionCallWithoutParens
|
||||||
|
|
||||||
|
possiblyNestedFunctionCall
|
||||||
|
= first:expression nested:expression* last:expression { return unnestFunctionCalls(first, nested, last); }
|
||||||
|
|
||||||
|
assignment
|
||||||
|
= _ identifier:identifier
|
||||||
|
_ "="
|
||||||
|
_ expression:expression
|
||||||
|
_ ";" { return {type: "assignment", identifier: identifier, expression: expression} }
|
||||||
|
|
||||||
|
assignmentList
|
||||||
|
= items:assignment* { return items; }
|
||||||
|
|
||||||
|
bindingList
|
||||||
|
= items:assignment* { return {type: "bindings", assignments: items} }
|
||||||
|
|
||||||
|
set
|
||||||
|
= "{"
|
||||||
|
_ items:assignmentList
|
||||||
|
_ "}" { return {type: "set", assignments: items} }
|
||||||
|
|
||||||
|
recursiveSet
|
||||||
|
= "rec"
|
||||||
|
_ setData:set { return {type: "recursiveSet", assignments: setData.assignments} }
|
||||||
|
|
||||||
|
letBlock
|
||||||
|
= "let"
|
||||||
|
_ bindingList:bindingList
|
||||||
|
_ "in"
|
||||||
|
_ expression:expression { return {type: "letBlock", bindings: bindingList.assignments, expression: expression} }
|
||||||
|
|
||||||
|
setPattern
|
||||||
|
= "{"
|
||||||
|
_ args:setPatternVariableList
|
||||||
|
_ "}" { return {type: "setPattern", variables: args} }
|
||||||
|
|
||||||
|
setPatternVariableList
|
||||||
|
= firstItem:setPatternVariable otherItems:(_ "," _ setPatternVariable)* { return concatRepeat(firstItem, otherItems, 3); }
|
||||||
|
|
||||||
|
setPatternVariable
|
||||||
|
= restParameter
|
||||||
|
/ identifier
|
||||||
|
|
||||||
|
restParameter
|
||||||
|
= "..." { return {type: "restParameter"} }
|
@ -0,0 +1,7 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const expressionParser = require("./expression");
|
||||||
|
|
||||||
|
module.exports = function(body) {
|
||||||
|
return expressionParser.parse(body);
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const util = require("util");
|
||||||
|
const fs = require("fs");
|
||||||
|
const parse = require("./");
|
||||||
|
|
||||||
|
function fullInspect(obj) {
|
||||||
|
return util.inspect(obj, {colors: true, depth: null, customInspect: false})
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let contents = fs.readFileSync(process.argv[2]).toString();
|
||||||
|
console.log(fullInspect(parse(contents)));
|
||||||
|
} catch (err) {
|
||||||
|
console.log(fullInspect(err))
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
builtins.isInt 4
|
@ -0,0 +1 @@
|
|||||||
|
builtins.isInt(4)
|
@ -0,0 +1,7 @@
|
|||||||
|
let
|
||||||
|
h = "Hello";
|
||||||
|
w = "World";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
helloWorld = h + X + X;
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
builtins.isInt 4 10 12
|
@ -0,0 +1,7 @@
|
|||||||
|
{ system, bootStdenv, noSysDirs, gccWithCC, gccWithProfiling
|
||||||
|
, config, crossSystem, platform, lib
|
||||||
|
, pkgsWithOverrides
|
||||||
|
, ... }:
|
||||||
|
rec {
|
||||||
|
thing = config;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
# code goes here
|
||||||
|
{
|
||||||
|
v="understood"; # Another comment
|
||||||
|
b=2;
|
||||||
|
}
|
Loading…
Reference in New Issue