XCFramework打包专用

xcbosa-itx b7ec62d61f Fix memory leak %!s(int64=2) %!d(string=hai) anos
GithubImages 72a040cbbd Add example img 2 %!s(int64=2) %!d(string=hai) anos
TestApp 4c132f31f5 Add auto converting for export values, add string(chinese:english:) and string(english:chinese:) %!s(int64=2) %!d(string=hai) anos
XCTreeLang b7ec62d61f Fix memory leak %!s(int64=2) %!d(string=hai) anos
XCTreeLang.xcodeproj b7ec62d61f Fix memory leak %!s(int64=2) %!d(string=hai) anos
.DS_Store ce27dc1a7c Support lazy's lazy, lazy rescursion %!s(int64=2) %!d(string=hai) anos
.gitignore 5e4a1edb19 Add XCFramework %!s(int64=2) %!d(string=hai) anos
LICENSE 88f5cc4583 Create LICENSE %!s(int64=2) %!d(string=hai) anos
README.md e882dcc77f Add image for readme %!s(int64=2) %!d(string=hai) anos
XCFramework.sh 5e4a1edb19 Add XCFramework %!s(int64=2) %!d(string=hai) anos

README.md

(WIP) XCTreeLang (XCT) Interpreter

一种基于iOS Runtime的脚本语言,支持优雅的调用OC的函数。

这个项目最开始的目的是作为依赖注入的配置文件格式,后续慢慢的加入可执行语句,进而想要做一种脚本语言。

ImageExample1

ImageExample2

由于是全新的语法,且需要支持OC互操作,所以加了一些专属特性。例如,在JSPatch中,您可能会这么写:

table.indexPathForRow_inSection(1, 0)

但是在XCT中,只需要

table.indexPath(row: 1 section: 0)
// XCT会在selector中自动插入with or for or in来调用

XCT的目标之一是消灭所有终结符,利用上下文推导语句结束,因此,分号和逗号在这个语言里是完全不存在的TokenType。

基本语法

1. 定义变量

set a = <Expr>

XCT不区分变量初始化和赋值,但每个对单个变量赋值的语句都需要前面有个set。

XCT的类型系统包含基础类型、 变量类型XCTLRuntimeVariableType有: | 变量类型 | 描述 | | --- | --- | | typeVoid | nil or no return value | | typeObject | a NSObject object | | typeString | a string | | typeNumber | We only use double as number type | | typeBoolean | true or false | | typeFuncIntrinsic | A native NSBlock object, which can be call in script | | typeFuncImpl | A paragraph definition statement |

2. 条件语句 switch-than

对于任何判断场景,我们只提供switch-than语句。这是一种特殊且优雅的switch语句,其中的每个than条目(就像其它语言的case条目)允许逻辑重叠。

switch <Expr> {
    <ThanStmt1>
    <ThanStmt2>
    ...
}

其中,Than语句有equalthan、morethan、lessthan与else,至于用法,就像说话一样。

例如,我们写一个判断版本执行不同函数的代码

switch appBundleVersion {
    lessthan 30 { nextthan }
    equalthan 30 {
        initialize_app_with_30()
        // 如果小于等于30,则执行这个函数
    }
    lessthan 60 { nextthan }
    equalthan 60 {
        initialize_app_with_60()
        // 如果小于等于60,则执行这个函数
    }
    else {
        log("Warning: Unknown version")
        initialize_app_with_60()
        // 如果其它,则执行这个函数且警告
    }
}

3. 循环语句 for-in

For-In语句遍历的对象必须实现了XCTLEnumerator或XCTLEnumeratorProvider协议。XCTLEnumerator代表迭代器本身,XCTLEnumeratorProvider代表提供迭代器的容器(例如NSArray)。如需要您可通过Category为自定义类实现迭代器。

for <loop_variable_name> in <Expr> {
    // Todo: Do somethings
}

4.函数定义语句

函数定义的关键词一开始是paragraph,但由于它太长了,且很与众不同,所以也加入了一些常见关键词:func和function。它们实际上都是一个TokenType,没有区别。

// 无参数函数定义
paragraph <paragraph_name> {
    <Stmt1>
    <Stmt2>
    ...
}

// 有参数函数定义 abc:_:
paragraph abc(arg1 arg2) {
    ...
}
// 调用:abc(1 2)

// 有标签参数函数定义 abcWithArgLabel1:argLabel2:
paragraph abc(argLabel1:arg1 argLabel2:arg2) {

}
// 调用:abc(argLabel1:1 argLabel2:2)

5.构造语句

由于此项目初衷是配置文件,所以对构造实例的语法特殊设计。

<class_type> <variable_name> {
    [arg1]
    [arg2]
    ...
} [{
    [LateExpr1]
    [LateExpr2]
    ...
}]

// 第二组大括号可有可无,代表当所有代码执行完时最后执行的内容。

如果构造的变量要自动注入到OC代码的实例中,需要使用export语句指定变量需要注入。如果要从OC代码实例中获取成员,则需要使用import语句引入。这两个语句都需要写在文档的开头。

import mySomeView
export previewViewController

XCTLViewController previewViewController {
    mySomeView
} {
    .view.backgroundColor = UIColor.cyanColor
}