Skip to content

Instantly share code, notes, and snippets.

@zwade
Created July 15, 2015 20:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zwade/c5f7925230dd1b5214ce to your computer and use it in GitHub Desktop.
Save zwade/c5f7925230dd1b5214ce to your computer and use it in GitHub Desktop.
LAML -- Lazy-Butt Markup Language, pronounced Lame-al -- Transpiler. See Below for input (schema.laml) and output (schema.js). Note, it outputs JS, not JSON to allow for the embedding of functions within the markup language.
funcs = []
function main() {
fs = require("fs")
file = fs.readFileSync(process.argv[2] || "schema.laml").toString()
empty = file.split(/\n+/)
var out = {}
var level = 0
var res = parseBlock(empty, 0, 0)[0]
var stringed = JSON.stringify(res)
for (var f in funcs) {
stringed = stringed.replace("\"<<LAMLKEY-"+f+">>\"", funcs[f])
}
var name = (process.argv[2] || "schema.laml").split(".")[0]
var fin = "(function() { "+name+" = "+stringed+" })()"
fs.writeFileSync(process.argv[3] || name+".js", fin)
}
function parseBlock(block, index, level) {
var isArray;
var ret;
if (parseType(block[index]) == "object") {
ret = {}
isArray = false
} else {
ret = []
isArray = true
}
for (var i = index; i < block.length; i++) {
var localIndex = i-(1+index)
var regex = /(\t*)(.+)/
var ex = regex.exec(block[i])
if (!ex) {
continue;
}
if (ex[1].length < level) {
if (isArray && ret.length == 1) {
ret = ret[0]
}
return [ret, i-1];
}
if (!isArray && parseType(block[i]) != "object") {
isArray = true;
ret = encapsulate(ret)
}
switch(parseType(block[i])) {
case "object":
var regex = /(\t*)(.*):/
var name = regex.exec(block[i])[2]
var out = parseBlock(block, i+1, level+1)
i = out[1]
if (isArray) {
if (!name) {
ret.push(out[0])
} else {
var obj = {}
obj[name] = out[0]
ret.push(obj)
}
} else {
ret[name] = out[0]
}
break;
case "function":
ret.push(parseFunction(ex[2]))
break;
case "inPlaceArray":
ret.push(parseArray(ex[2]))
break;
case "number":
ret.push(parseInt(ex[2]))
break;
case "float":
ret.push(parseFloat(ex[2]))
break;
default:
ret.push(parseString(ex[2]))
}
}
if (isArray && ret.length == 1) {
ret = ret[0]
}
return [ret,i];
}
function parseType(line) {
var tmpr = /\t+\"(.+)\"/
if (tmpr[1]) {
return "string"
}
if (line.indexOf("->") > 0) {
return "function";
}
if (line.indexOf(":") > 0) {
return "object"
}
if (line.indexOf(",") > 0) {
return "inPlaceArray"
}
if (!isNaN(line) && line.indexOf(".")) {
return "float"
}
if (!isNaN(line)) {
return "int"
}
return "string"
}
parseFunction = function(line) {
var out = "<<LAMLKEY-"+funcs.length+">>"
var tmpr = /\t*(([a-zA-Z0-9]+)|(\([a-zA-Z0-9, -]+\))) *->[ \t]*(.*)/
var res = tmpr.exec(line)
var f;
if (res[3]) {
f = "function"+res[3]+" { return "+res[4]+" }"
} else if (res[2]) {
f = "function() { "+res[2]+" = "+res[4]+" } "
}
funcs.push(f)
return out;
}
parseArray = function(line) {
var regex = /([\t ]*)([^,]+)[\t ]*(,|([\t ]*$))/g
var match = regex.exec(line)
var out = []
while (match) {
out.push(match[2])
match = regex.exec(line)
}
return out
}
parseString = function(line) {
return line;
}
encapsulate = function(obj) {
var ret = []
for (var key in obj) {
var tmp = {}
tmp[key] = obj[key]
ret.push(tmp)
}
return ret
}
main()
(function() {
schema = {
"Stats": ["health", "money", "level"],
"Hidden": ["hunger", "happiness", "stress", "dedication", "tiredness", "intelligence", "sanity", "popularity"],
"Attributes": ["very fast", "motivated", "smart", {
"speed": 3,
"intelligence": 4
}],
"Actions": [{
"Eat": [function() {
hunger = 40 + 0.6 * hunger
}
, function() {
money = money - Math.random() * 10 + 5
}
, function() {
time = time + 1 / 48
}
]
}, {
"Play": [function() {
level = level + Math.random() * 0.1
}
, function() {
popularity = popularity - 0.8
}
, function() {
time = time + 1 / 24
}
]
}, {
"Add": []
}, function(a, b) {
return a + b
}
]
}
}
)()
Stats:
health, money, level
Hidden:
hunger, happiness, stress, dedication, tiredness, intelligence, sanity, popularity
Attributes:
very fast
motivated
smart
:
speed:
3
intelligence:
4
Actions:
Eat:
hunger -> 40+0.6*hunger
money -> money - Math.random() * 10 + 5
time -> time + 1/48
Play:
level -> level+Math.random() * 0.1
popularity -> popularity - 0.8
time -> time + 1/24
Add:
(a,b) -> a+b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment