Skip to content

Instantly share code, notes, and snippets.

@marihachi
Last active April 5, 2020 07:57
Show Gist options
  • Save marihachi/f3e6c5de3d8c000d70c928dee078b37b to your computer and use it in GitHub Desktop.
Save marihachi/f3e6c5de3d8c000d70c928dee078b37b to your computer and use it in GitHub Desktop.
ai script parser (wip)
interface INode {
type: string;
children?: INode[];
[x: string]: any;
}
interface BooleanLiteral extends INode {
type: 'bool';
value: boolean;
}
interface NumberLiteral extends INode {
type: 'number';
value: number;
}
interface StringLiteral extends INode {
type: 'string';
value: string;
}
interface ObjectLiteral extends INode {
type: 'object';
object: {
key: string;
value: INode;
}[];
}
interface FunctionObject extends INode {
type: 'func';
args: string[];
children: INode[];
}
interface Variable extends INode {
type: 'var';
name: string;
}
interface VariableDefinitionStatement extends INode {
type: 'def';
name: string;
expr: INode;
}
interface FuncDefinitionStatement extends VariableDefinitionStatement {
expr: FunctionObject;
}
// statement or expression
interface CallFunc extends INode {
type: 'call';
name: string;
args: INode[];
}
interface ReturnStatement extends INode {
type: 'return';
expr: INode;
}
interface IfStatement extends INode {
type: 'if';
cond: INode;
then: INode[];
elseif: {
cond: INode;
then: INode[];
}[];
else: INode[];
}
{
function createNode(type, params, children) {
const node = { type };
params.children = children;
for (const key of Object.keys(params)) {
if (params[key] != null) {
node[key] = params[key];
}
}
return node;
}
}
start
= _ content:statements? _
{ return content; }
statements
= head:statement tails:(___ s:statement { return s; })*
{ return [head, ...tails]; }
statement
= varDefinition
/ if
/ return
/ fnDefinition
/ fnCall
expression
= numberLiteral
/ stringLiteral
/ booleanLiteral
/ fnObject
/ fnCall
/ variable
// statement of variable definition
varDefinition
= "#" [ \t]* name:NAME _ "=" _ expr:expression
{ return createNode('def', { name, expr: expr }); }
// statement of return
return
= "<<" _ expr:expression
{ return createNode('return', { expr }); }
// general expression --------------------------------------------------------------------
// variable reference
variable
= name:NAME
{ return createNode('var', { name }); }
// number literal
numberLiteral
= [+-]? [1-9] [0-9]+
{ return createNode('number', { value: parseInt(text(), 10) }); }
/ [+-]? [0-9]
{ return createNode('number', { value: parseInt(text(), 10) }); }
// string literal
stringLiteral
= "\"" vlaue:$(!"\"" .)* "\""
{ return createNode('string', { vlaue }); }
// boolean literal
booleanLiteral
= "true"
{ return createNode('bool', { value: true }); }
/ "false"
{ return createNode('bool', { value: false }); }
// function ------------------------------------------------------------------------------
fn_args
= head:NAME tails:(_ "," _ name:NAME { return name; })*
{ return [head, ...tails]; }
// statement of function definition
fnDefinition
= "@" __ name:NAME __ "(" _ args:fn_args? _ ")" _ "{" _ content:statements? _ "}"
{
return createNode('def', {
name: name,
expr: createNode('func', { args }, content)
});
}
// function object
fnObject = "@" _ "(" _ args:fn_args? _ ")" _ "{" _ content:statements? _ "}"
{ return createNode('func', { args }, content); }
// function call
fnCall
= name:NAME _ "(" _ args:fnCall_args? _ ")"
{ return createNode('call', { name, args }); }
fnCall_args
= head:expression tails:(_ "," _ expr:expression { return expr; })*
{ return [head, ...tails]; }
// if statement --------------------------------------------------------------------------
if
= "?" _ cond:expression _ "{" _ then:statements? _ "}" elseif:(_ b:elseifBlocks { return b; })? elseBlock:(_ b:elseBlock { return b; })?
{
return createNode('if', {
cond: cond,
then: then || [],
elseif: elseif || [],
else: elseBlock || []
});
}
elseifBlocks
= head:elseifBlock tails:(_ i:elseifBlock { return i; })*
{ return [head, ...tails]; }
elseifBlock
= "...?" _ cond:expression _ "{" _ then:statements? _ "}"
{ return { cond, then }; }
elseBlock
= "..." _ "{" _ then:statements? _ "}"
{ return then; }
// general -------------------------------------------------------------------------------
NAME = [A-Za-z] [A-Za-z0-9]* { return text(); }
// optional spacing
_
= [ \t\r\n]*
// optional spacing (no linebreaks)
__
= [ \t]*
// required spacing
___
= [ \t\r\n]+

組み込み関数の一覧
名前は変わるかも。

add

@add(a, b) 加算 A+B

引数

  • 左辺の式A
  • 右辺の式B

sub

@sub(a, b) 減算 A-B

引数

  • 左辺の式A
  • 右辺の式B

multiply

@multiply(a, b) 乗算 A*B

引数

  • 左辺の式A
  • 右辺の式B

div

@div(a, b) 除算 A/B

引数

  • 左辺の式A
  • 右辺の式B

eq

@eq(a, b) 一致 A==B

引数

  • a: boolean 比較対象A
  • b: boolean 比較対象B

戻り値

boolean

neq

@neq(a, b) 不一致 A != B

引数

  • a: boolean 比較対象A
  • b: boolean 比較対象B

戻り値

boolean

gt

@gt(a, b) bよりaが大きい A > B

引数

  • a: boolean 比較対象A
  • b: boolean 比較対象B

戻り値

boolean

lt

@lt(a, b) bよりaが小さい A < B

引数

  • a: boolean 比較対象A
  • b: boolean 比較対象B

戻り値

boolean

and

@and(a, b) A && B

引数

  • a: boolean
  • b: boolean

戻り値

boolean

or

@or(a, b)

引数

  • a: boolean
  • b: boolean

戻り値

boolean

not

@not(a)

引数

  • a: boolean
  • b: boolean

戻り値

boolean

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment