From fa7eb90f5d91cea76234fa1f1c7efdcbe9679fa2 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Mon, 23 May 2016 17:01:10 +0000 Subject: [PATCH] Initial commit --- index.js | 20 ++++++++++++ package.json | 27 ++++++++++++++++ src/parse/ast/table-to-array.js | 11 +++++++ src/parse/ast/table-to-object.js | 13 ++++++++ src/parse/ast/table-to-structure.js | 21 ++++++++++++ src/parse/ast/value.js | 16 +++++++++ src/parse/recipes.js | 50 +++++++++++++++++++++++++++++ 7 files changed, 158 insertions(+) create mode 100644 index.js create mode 100644 package.json create mode 100644 src/parse/ast/table-to-array.js create mode 100644 src/parse/ast/table-to-object.js create mode 100644 src/parse/ast/table-to-structure.js create mode 100644 src/parse/ast/value.js create mode 100644 src/parse/recipes.js diff --git a/index.js b/index.js new file mode 100644 index 0000000..832c7a7 --- /dev/null +++ b/index.js @@ -0,0 +1,20 @@ +'use strict'; + +const Promise = require("bluebird"); +const fs = Promise.promisifyAll(require("fs")); +const path = require("path"); +const util = require("util"); + +const parseRecipes = require("./src/parse/recipes"); + +Promise.try(() => { + return fs.readdirAsync(process.argv[2]); +}).map((file) => { + return fs.readFileAsync(path.join(process.argv[2], file)); +}).map((fileContents) => { + return parseRecipes(fileContents.toString()); +}).reduce((allRecipes, recipes) => { + return allRecipes.concat(recipes); +}, []).then((results) => { + console.log(util.inspect(results, {depth: null, colors: true})); +}); \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..523d78f --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "factorio-calculator", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git@git.cryto.net:joepie91/factorio-calculator.git" + }, + "author": "Sven Slootweg", + "license": "WTFPL", + "dependencies": { + "bluebird": "^3.3.5", + "in-array": "^0.1.2", + "luaparse": "^0.2.1", + "vivagraphjs": "^0.8.1", + "xtend": "^4.0.1" + }, + "devDependencies": { + "babel-loader": "^6.2.4", + "babel-preset-es2015": "^6.6.0", + "webpack": "^1.13.1" + } +} diff --git a/src/parse/ast/table-to-array.js b/src/parse/ast/table-to-array.js new file mode 100644 index 0000000..917b85e --- /dev/null +++ b/src/parse/ast/table-to-array.js @@ -0,0 +1,11 @@ +'use strict'; + +const parseValue = require("./value"); + +module.exports = function tableToArray(table) { + return table.fields.filter((field) => { + return (field.type === "TableValue"); + }).map((field) => { + return parseValue(field.value); + }); +} \ No newline at end of file diff --git a/src/parse/ast/table-to-object.js b/src/parse/ast/table-to-object.js new file mode 100644 index 0000000..dcd0351 --- /dev/null +++ b/src/parse/ast/table-to-object.js @@ -0,0 +1,13 @@ +'use strict'; + +const parseValue = require("./value"); + +module.exports = function tableToObject(table) { + return table.fields.filter((field) => { + return (field.type === "TableKeyString"); + }).reduce((obj, field) => { + // FIXME: Non-Identifier keys? + obj[field.key.name] = parseValue(field.value); + return obj; + }, {}); +} \ No newline at end of file diff --git a/src/parse/ast/table-to-structure.js b/src/parse/ast/table-to-structure.js new file mode 100644 index 0000000..d11b231 --- /dev/null +++ b/src/parse/ast/table-to-structure.js @@ -0,0 +1,21 @@ +'use strict'; + +const tableToObject = require("./table-to-object"); +const tableToArray = require("./table-to-array"); + +module.exports = function tableToStructure(table) { + let hasKeys = (table.fields.some((field) => field.type === "TableKeyString")); + let hasArrayValues = (table.fields.some((field) => field.type === "TableValue")); + + if (hasKeys && hasArrayValues) { + let obj = tableToObject(table); + obj._ = tableToArray(table); + return obj; + } else if (hasKeys) { + return tableToObject(table); + } else if (hasArrayValues) { + return tableToArray(table); + } else { + throw new Error("Neither array values nor keys found in table"); + } +} \ No newline at end of file diff --git a/src/parse/ast/value.js b/src/parse/ast/value.js new file mode 100644 index 0000000..4f70740 --- /dev/null +++ b/src/parse/ast/value.js @@ -0,0 +1,16 @@ +'use strict'; + +const inArray = require("in-array"); + +module.exports = function parseValue(item) { + /* We require() this here due to circular imports... */ + const tableToStructure = require("./table-to-structure"); + + if (item.type === "TableConstructorExpression") { + return tableToStructure(item); + } else if (inArray(["BooleanLiteral", "NumericLiteral", "StringLiteral"], item.type)) { + return item.value; + } else { + throw new Error(`Unknown type ${item.type} encountered`); + } +} \ No newline at end of file diff --git a/src/parse/recipes.js b/src/parse/recipes.js new file mode 100644 index 0000000..de28bc2 --- /dev/null +++ b/src/parse/recipes.js @@ -0,0 +1,50 @@ +'use strict'; + +const luaParser = require("luaparse"); +const xtend = require("xtend"); +const parseValue = require("./ast/value"); + +module.exports = function(luaCode) { + let parsedFile = luaParser.parse(luaCode); + let dataRoot = parsedFile.body[0].expression.arguments[0]; + let dataItems = parseValue(dataRoot); + + return dataItems.filter((item) => { + return item.type === "recipe"; + }).map((recipe) => { + let clonedRecipe = xtend(recipe); + delete clonedRecipe.type; + delete clonedRecipe.name; + + clonedRecipe.ingredients = clonedRecipe.ingredients.map((item) => { + if (Array.isArray(item)) { + return { + key: item[0], + value: { + type: "item", + amount: item[1] + } + } + } else { + let clonedIngredient = xtend(item); + delete clonedIngredient.name; + + return { + key: item.name, + value: clonedIngredient + } + } + }).reduce((allIngredients, ingredient) => { + allIngredients[ingredient.key] = ingredient.value; + return allIngredients; + }, {}); + + return { + key: recipe.name, + value: clonedRecipe + } + }).reduce((allRecipes, recipe) => { + allRecipes[recipe.key] = recipe.value; + return allRecipes; + }, {}); +} \ No newline at end of file