Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ jobs:
dist/bin/ako.exe
dist/bin/ako-linux
dist/bin/ako-osx
dist/node/ako.js
dist/web/ako-web.js
dist/ako-node.js
dist/ako-web.js
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"build:types:web-light": "node ./tools/gen-typings.js ako-weblight",
"build:post": "node ./tools/prepend.js",
"coverage": "nyc --reporter=text-lcov mocha ./tests/**.test.ts > coverage.lcov",
"coverage-user": "nyc mocha ./tests/**.test.ts",
"package": "run-s package:*",
"package:win": "cd dist && nexe --input=./ako-cli.js --output=./bin/ako.exe --target=win-12.12.0",
"package:macos": "cd dist && nexe --input=./ako-cli.js --output=./bin/ako-osx --target=darwin-12.12.0",
Expand Down
12 changes: 6 additions & 6 deletions samples/math/module.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "Math module",
"namespace": "Math",
"deps": [
"../vec"
]
}
"id": "Math module",
"namespace": "Math",
"deps": [
"../vec"
]
}
14 changes: 8 additions & 6 deletions samples/module.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"id": "Test Project",
"entry": ["main.ako"],
"deps": [
"./math"
]
}
"id": "Test Project",
"entry": [
"main.ako"
],
"deps": [
"./math"
]
}
8 changes: 4 additions & 4 deletions samples/vec/module.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"id": "Vec module",
"namespace": "Vec",
"deps": []
}
"id": "Vec module",
"namespace": "Vec",
"deps": []
}
3 changes: 2 additions & 1 deletion src/ako_grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ Ako {
Metadata = "##" Id Term

TaskDef = "task" Id (Array)? Block
Task = "@" (Id ".")? Id "(" Arguments ")"
Task = "@" (Id ".")? Id "(" NamedArguments ")"
NamedArguments = ListOf<(KeyValue | Expr), ",">
Arguments = ListOf<Expr, ",">

// Expression
Expand Down
21 changes: 1 addition & 20 deletions src/dist/ako-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,8 @@ function loadAkoModule(vm: Interpreter, projectFolder: string) {
if (vm.tasks.has(methodName)) {
throw new Error(`Task Name Already Used : ${methodName}`)
}
vm.registerTask(methodName, (ctx, _, fnData, timeRemains) => {
if (!fnData.meta.block) {
const argsMeta = ast.filter((x) => x.type === 'Metadata' && x.key === 'Args')
const block = ctx.vm.createStack(ast)
ctx.vm.setData({vm: ctx.vm, stack: block}, 'args', fnData.meta.args || [])
if (argsMeta && argsMeta[0]) {
const val = ctx.vm.evaluate(ctx, argsMeta[0].value, true)
for (let i = 0; i < val.length; i++) {
if (!val[i] || !val[i].name) continue
if (i < fnData.meta.args.length) ctx.vm.setData({vm: ctx.vm, stack: block}, val[i].name, fnData.meta.args[i])
else if ('default' in val[i]) ctx.vm.setData({vm: ctx.vm, stack: block}, val[i].name, val[i].default)
}
}
fnData.meta.block = block.uid
}

const stack = ctx.vm.stacks.get(fnData.meta.block) as Stack
const res = ctx.vm.updateStack(stack, timeRemains, true)
if (res.done) res.result = stack.result
return res
})
vm.addFile(methodName, ast)
}

// execute entry point
Expand Down
40 changes: 24 additions & 16 deletions src/elements/function.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {mapArgs} from '../helpers/args'

export const Metadata = {
create: (key: any, value: any) => {
return {type: 'Metadata', key: key.value ? key.value : key, value}
Expand Down Expand Up @@ -32,7 +34,23 @@ export const Task = {
const namespace = ctx.vm.evaluate(ctx, entry.namespace[0], true)
fn = `${namespace}.${fn}`
}
const args = entry.args.map((x) => ctx.vm.evaluate(ctx, x, true))
let i = -1
const args = entry.args.map((x) => {
if (x.type === 'KeyValue') {
return {
type: 'NamedArgs',
name: ctx.vm.evaluate(ctx, x.symbol, true),
value: ctx.vm.evaluate(ctx, x.value, true)
}
}
i = i + 1
return {
type: 'Args',
index: i,
value: ctx.vm.evaluate(ctx, x, true)
}
})
// console.log(args)
entryData.meta = {fn, args}
}

Expand All @@ -49,19 +67,12 @@ export const TaskDef = {
execute: (ctx, entry, entryData, timeRemains) => {
ctx.vm.registerTask(entry.name.value, (ctx2, entry2, entryData2, time) => {
if (!entryData2.meta.block) {
const directArgs = entry.args.map((x) => ctx.vm.evaluate(ctx, x, true))
const argsMeta = entry.block.statements.filter((x) => x.type === 'Metadata' && x.key === 'Args')
const args = mapArgs(ctx, entry.args, entry.block.statements, entryData2.meta.args || [])
const block = ctx2.vm.createStack(entry.block.statements)
ctx2.vm.setData({vm: ctx2.vm, stack: block}, 'args', entryData2.meta.args || [])
if (directArgs || (argsMeta && argsMeta[0])) {
const val = ctx.vm.evaluate(ctx, directArgs || argsMeta[0].value, true)
for (let i = 0; i < val.length; i++) {
if (!val[i]) continue
const name = val[i].name || val[i]
if (i < entryData2.meta.args.length) ctx2.vm.setData({vm: ctx2.vm, stack: block}, name, entryData2.meta.args[i])
else if ('default' in val[i]) ctx.vm.setData({vm: ctx2.vm, stack: block}, name, val[i].default)
}
for (const key in args) {
ctx2.vm.setData({vm: ctx2.vm, stack: block}, key, args[key])
}
ctx2.vm.setData({vm: ctx2.vm, stack: block}, 'args', Object.values(args))
entryData2.meta.block = block.uid
}

Expand All @@ -84,11 +95,8 @@ export const Function = {
const entries = entry.namespace.map((x) => ctx.vm.evaluate(ctx, x))
fn = `${entries.join(',')}.${ctx.vm.evaluate(ctx, entry.name)}`
}

const args = entry.args.map((x) => ctx.vm.evaluate(ctx, x, true))

// console.log('Call function', fn, entry, args)
return ctx.vm.callFunction(fn, args)
return ctx.vm.callFunction(fn, ...args)
}
}

Expand Down
45 changes: 45 additions & 0 deletions src/helpers/args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {Context} from '../core'

export function mapArgs(ctx: Context, taskDefArgs: any, blocks: any, values: any) {
// console.log(taskDefArgs, blocks)
const taskDefMetaArgs = taskDefArgs.filter((x) => !!x).map((x: any) => ctx.vm.evaluate(ctx, x, true))
const inlineMetaArgs = blocks
.filter((x: any) => !!x && x.type === 'Metadata' && x.key === 'Args')
.map((x: any) => x.value.value.map((y) => ctx.vm.evaluate(ctx, y, true)))

let args = []
if (taskDefMetaArgs.length > 0) {
args = taskDefMetaArgs.map((val, index) => {
if (typeof val === 'string' || val instanceof String) {
return {index, name: val}
} else {
return {...val, index}
}
})
} else if (inlineMetaArgs.length > 0) {
args = inlineMetaArgs[0].map((x, index) => {
return {...x, index}
})
}

const params: {[id: string]: any} = {}
for (const arg of args) {
if ('default' in arg) params[arg.name] = arg.default
}
for (const arg of values) {
if (arg.type === 'Args') {
const entry = args.find((x) => x.index === arg.index)
if (entry) {
params[entry.name] = arg.value
} else {
params[`param_${arg.index}`] = arg.value
}
} else if (arg.type === 'NamedArgs') {
const entry = args.find((x) => x.name === arg.name)
if (entry) params[entry.name] = arg.value
}
}

// console.log('Params >>', params, values, '<<')
return params
}
21 changes: 21 additions & 0 deletions src/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {uid} from './helpers/id'
import * as AkoElement from './elements'
import {stdTasks, stdFunctions} from './std'
import {Task, Context, Func, Stack, UpdateStackResult} from './core'
import {mapArgs} from './helpers/args'

export class Interpreter {
stacks: Map<string, Stack> = new Map<string, Stack>()
Expand Down Expand Up @@ -35,6 +36,25 @@ export class Interpreter {
return stack
}

addFile(name: string, ast: any): void {
this.registerTask(name, (ctx, fn, fnData, timeRemains) => {
if (!fnData.meta.block) {
const args = mapArgs(ctx, [], ast, fnData.meta.args)
const block = ctx.vm.createStack(ast)
for (const key in args) {
ctx.vm.setData({vm: ctx.vm, stack: block}, key, args[key])
}
ctx.vm.setData({vm: ctx.vm, stack: block}, 'args', Object.values(args))
fnData.meta.block = block.uid
}

const stack = ctx.vm.stacks.get(fnData.meta.block) as Stack
const res = ctx.vm.updateStack(stack, timeRemains, true)
if (res.done) res.result = stack.result
return res
})
}

registerFunction(name: string, method: Func): void {
this.functions.set(name, method)
}
Expand Down Expand Up @@ -62,6 +82,7 @@ export class Interpreter {

evaluate(ctx: Context, expr, resolveSymbol = false): any {
if (!expr || !expr.type) return expr
if (!AkoElement[expr.type].evaluate) throw new Error(`Cannot Evaluate ${expr.type}`)
return AkoElement[expr.type].evaluate(ctx, expr, resolveSymbol)
}

Expand Down
1 change: 0 additions & 1 deletion src/semantic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export function getGrammar(akoGrammar: string) {
return parseFloat(this.sourceString)
},
hex: function (a, b) {
console.log(this.sourceString)
return Number(`0x${this.sourceString.slice(1)}`)
}
})
Expand Down
22 changes: 12 additions & 10 deletions src/std/collections/list.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
export const list = {
'List.filter': (args: [any[], (item: any, index: number) => any]) => {
const [arr, lambda] = args
'List.filter': (arr: number[], lambda: (item1: number, item2: number) => number): number[] => {
return arr.filter(lambda)
},
'List.map': (args: [any[], (item: any, index: number) => any]) => {
const [arr, lambda] = args
'List.map': (arr: number[], lambda: (item: number) => number): number[] => {
return arr.map(lambda)
},
'List.sort': (args: [any[], (item1: any, item2: any) => number]) => {
const [arr, lambda] = args
return lambda ? arr.sort(lambda) : arr.sort()
'List.sort': (arr: number[], lambda: (item1: number, item2: number) => number): number[] => {
return lambda
? [...arr].sort(lambda)
: [...arr].sort((a, b) => {
if (a < b) return -1
if (a > b) return 1
return 0
})
},
'List.reverse': (args: [any[]]) => {
const [arr] = args
return arr.reverse()
'List.reverse': (arr: number[]): number[] => {
return [...arr].reverse()
}
}
27 changes: 9 additions & 18 deletions src/std/geometry/vector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,45 @@ import {deg2rad, rad2deg} from './angle'

type Vec2 = [number, number]

const create = (args?: number[]) => {
const create = (...args: number[]): Vec2 => {
const [x, y] = args || []
return [x || 0, y || 0] as Vec2
}
const clone = (arg: Vec2) => create(arg)
const precisionRoundVec = (arg: Vec2, precision = 7) => {
const clone = (args: Vec2) => create(...args)
const precisionRoundVec = (arg: Vec2, precision = 7): Vec2 => {
return [precisionRound(arg[0], precision), precisionRound(arg[1], precision)]
}

export const vector2 = {
'Vec2.create': create,
'Vec2.clone': (arg: Vec2[]) => {
return clone(arg[0])
},
'Vec2.add': (args: Vec2[]) => {
// console.log('Vector2 Add', args)
'Vec2.clone': (vec: Vec2): Vec2 => clone(vec),
'Vec2.add': (...args: Vec2[]): Vec2 => {
const vec = create()
for (const arg of args) {
vec[0] = vec[0] + arg[0] || 0
vec[1] = vec[1] + arg[1] || 0
}
return precisionRoundVec(vec)
},
'Vec2.sub': (args: Vec2[]) => {
'Vec2.sub': (...args: Vec2[]): Vec2 => {
const [origin, ...other] = args
const vec = clone(origin)
for (const arg of other) {
vec[0] = vec[0] - arg[0] || 0
vec[1] = vec[1] - arg[1] || 0
}
// console.log('Vector2 Sub', args, '=>', vec)
return precisionRoundVec(vec)
},
'Vec2.scale': (args: [Vec2, number]) => {
const [origin, scale] = args
'Vec2.scale': (origin: Vec2, scale: number): Vec2 => {
const vec = clone(origin)
vec[0] = precisionRound(vec[0] * scale)
vec[1] = precisionRound(vec[1] * scale)
// console.log('Vector2 Scale', origin, '*', scale, '=>', vec)
return precisionRoundVec(vec)
},
'Vec2.angle': (args: [Vec2]) => {
const [origin] = args
// console.log('Vector2 Angle', origin)
'Vec2.angle': (origin: Vec2): number => {
return precisionRound(rad2deg(Math.atan2(origin[1], origin[0])))
},
'Vec2.rotate': (args: [Vec2, number]) => {
const [origin, angle] = args
'Vec2.rotate': (origin: Vec2, angle: number): Vec2 => {
const rad = deg2rad(angle)
const cos = Math.cos(rad)
const sin = Math.sin(rad)
Expand Down
22 changes: 0 additions & 22 deletions src/std/system/cache.ts

This file was deleted.

3 changes: 1 addition & 2 deletions src/std/system/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import log from './print'
import sleep from './sleep'
import ask from './ask'
import cache from './cache'

export default {...log, ...sleep, ...ask, ...cache}
export default {...log, ...sleep, ...ask}
Loading