Fixes in lambda/function definitions (body args). Cleanup of examples and decumentation. Added convenience methods for JS interop, lists and objects.

This commit is contained in:
Kuba Antosik
2021-04-04 18:35:26 +10:00
parent 8d23e5264e
commit 0cebbe52cb
24 changed files with 655 additions and 120 deletions

View File

@@ -40,15 +40,21 @@ function Lain (lib = {}) {
defn: function (input, context) {
const identifier = input[1].value
if (context.scope[identifier]) { console.warn('Lain', `Redefining function: ${identifier}`) }
const fnParams = input[2].type === TYPES.string && input[3] ? input[3] : input[2]
const fnBody = input[2].type === TYPES.string && input[4] ? input[4] : input[3]
const fnBodyFirstIndex = input[2].type === TYPES.string && input[4] ? 4 : 3
const fnBody = input.slice(fnBodyFirstIndex)
context.scope[identifier] = function () {
const lambdaArguments = arguments
const lambdaScope = fnParams.reduce(function (acc, x, i) {
acc[x.value] = lambdaArguments[i]
return acc
}, {})
return interpret(fnBody, new Context(lambdaScope, context))
let result = interpret(fnBody, new Context(lambdaScope, context))
//lisp returns the return value of the last executed function, not a list of all results of all functions.
return getReturnValue(result)
}
},
λ: function (input, context) {
@@ -58,7 +64,10 @@ function Lain (lib = {}) {
acc[x.value] = lambdaArguments[i]
return acc
}, {})
return interpret(input[2], new Context(lambdaScope, context))
let result = interpret(input.slice(2), new Context(lambdaScope, context))
//lisp returns the return value of the last executed function, not a list of all results of all functions.
return getReturnValue(result)
}
},
if: function (input, context) {
@@ -66,6 +75,15 @@ function Lain (lib = {}) {
}
}
const getReturnValue = function (interpretResult) {
//lisp returns the return value of the last executed function,
//not a list of all results of all functions.
if(!interpretResult || !(interpretResult instanceof Array) || !interpretResult.length){
return interpretResult
}
return interpretResult[interpretResult.length - 1]
}
const interpretList = function (input, context) {
if (input.length > 0 && input[0].value in special) {
return special[input[0].value](input, context)