跳到主要内容

语法关键字

alias 是 Alia 语言的核心关键字,用于定义新的语法结构。本文档描述 alias 的定义形式、匹配机制与调用形式。

1. 基本语法​

alias <Keys pattern> -> <Stack implementation>
alias <Keys pattern> -> <Stack implementation> => <Key aliasName>
alias <Keys pattern> -> <Object type> <Stack implementation>
alias <Keys pattern> -> <Object type> <Stack implementation> => <Key aliasName>
alias <Keys pattern> => <Key aliasName>
alias <Keys pattern>
alias <Keys pattern> -> <Object type>

-> <Object type> 声明实现体的返回类型,=> <Key aliasName> 声明语法关键字的注册名称。无实现体的声明仅注册匹配形态,不产生可执行动作。

内联 Alias 表达式​

alias 作为表达式求值后返回一个 Alias 对象:

alias <Keys pattern> -> <Stack implementation>
alias <Keys pattern> -> <Object type> <Stack implementation>

内联 alias 表达式赋值给变量后,该变量持有 Alias 对象,可作为参数传递或存储在对象中。

const add = alias <Number a> and <Number b> -> Number { a + b }
assert (call add [1, 2]) == 3 error 'inline alias mismatch'

2. 匹配机制​

匹配优先级​

同时存在短项和长项定义时,代码中匹配到长项则执行长项:

alias testmatch <Boolean condition> <Stack stack> -> {
if condition { call stack.run }
}
alias testmatch <Boolean condition> <Stack stack1> else <Stack stack2> -> {
if condition { call stack1.run } else { call stack2.run }
}
let result1 = ''
testmatch true {
result1 = 'yes'
} else {
result1 = 'no'
}
assert result1 == 'yes' error 'long match mismatch'

3. 关键字别名​

=> 为一段匹配形态提供注册名称。形态首项不是关键字时,显式命名决定调用入口:

alias <Number a> and <Number b> -> Number { a + b } => add
assert (add 1 and 2) == 3 error 'named alias mismatch'

命名 alias 在定义后同时注册语法关键字与同名 Alias 对象。对象形态的存储与调用关系见第 4 节。

4. 匿名 Alias​

匿名 alias 没有注册名称,alias 表达式求值后返回 Alias 对象并赋值给变量:

const add = alias <Number a> and <Number b> -> Number { a + b }
assert (add 1 and 2) == 3 error 'anonymous alias mismatch'
const applyOperation = alias <Alias op> and <Number a> and <Number b> -> Number {
call op [a, b]
}
assert (call applyOperation [add, 5, 3]) == 8 error 'higher order mismatch'

alias 表达式在求值后返回一个 Alias 对象,该对象能够像普通值一样被存储和传递。

call 语法调用(动态分发)​

模式已知的调用优先采用语法式。call 数组/对象形式保留给运行时才能确定目标或参数形态的动态分发场景,以及表达式位置无法使用语法式的场景:

const add = alias <Number a> and <Number b> -> Number { a + b }
assert (call add [1, 2]) == 3 error 'array call mismatch'
assert (call add *[b:2, a:1]) == 3 error 'object call mismatch'
  • call alias [arg1, arg2, ...]:传入 Array,按照参数声明顺序传入值
  • call alias *[key:value, key2:value2, ...]:传入 Object,键名与参数名称对应,键值作为参数值

对象中的 Alias​

匿名 alias 存储在对象中后,通过成员目标发起调用:

const helpers = *[
add: alias <Number a> and <Number b> -> Number { a + b },
multiply: alias <Number a> and <Number b> -> Number { a * b }
]
assert (call helpers.add [3, 4]) == 7 error 'object alias add mismatch'
assert (call helpers.multiply [3, 4]) == 12 error 'object alias multiply mismatch'

无参数形态的取值与执行​

无参数语法关键字以独立语句形式执行,表达式位置取值需经 call。无参数 Alias 对象直接引用为获取对象,call 为执行:

let a = 21
let b = 21
alias plusAandB -> { a + b }
assert (call plusAandB) == 42 error 'keyword call mismatch'
const plusAandBObj = alias -> Number { a + b }
assert (call plusAandBObj) == 42 error 'object call mismatch'

5. 复杂模式匹配​

带参数的模式​

alias <Number a> plus <Number b> equals <Number c> -> Boolean {
a + b == c
}
assert (1 plus 2 equals 3) == true error 'pattern match mismatch'
assert (2 plus 3 equals 6) == false error 'pattern mismatch mismatch'

嵌套模式​

alias whenMatch <Boolean condition> then <Stack stack1> else <Stack stack2> -> {
condition ? call stack1.run : call stack2.run
}
let nestedResult = ''
whenMatch true then { nestedResult = 'yes' } else { nestedResult = 'no' }
assert nestedResult == 'yes' error 'nested match mismatch'

参数类型语义​

<Type name> 声明参数的匹配行为按类型区分:

  • <Stack stack>:匹配 Stack 值或栈字面量——栈字面量({}/*{}/-> {})、持有 Stack 的变量、返回 Stack 的表达式均可作为实参。静态类型须为 Stack,非 Stack 值(如数字、字符串)在检查期报 TYPE_ARGUMENT_MISMATCH,运行期报 RUNTIME_TYPE_ERROR。
  • <Alias aliasObject>:匹配 Alias 对象——alias ... -> {...} 字面量、持有 Alias 的变量或命名 alias 标识符都可以。实参的实际类型会被校验,非 Alias 值(如栈字面量、数字)在检查期报 TYPE_ARGUMENT_MISMATCH,运行期报 RUNTIME_TYPE_ERROR。
const apply = alias <Alias op> and <Number a> -> Number { call op [a] }
const incAlias = alias <Number x> -> Number { x }
assert (call apply [incAlias, 5]) == 5 error 'alias param mismatch'
let caught = false
try { call apply [{}, 5] } catch e { caught = true }
assert caught == true error 'alias type check mismatch'

<Alias> 参数在语法式调用与 call 数组/对象调用下均可接收存储的 Alias 对象。

6. 移除和禁用 Alias​

移除 Alias​

alias customPrint <Value val> -> {
print val
}
customPrint 'Hello'
remove customPrint

移除后该名称不再匹配,调用时报未定义别名错误:

alias tempAlias <Number val> -> Number {
val
}
assert (tempAlias 42) == 42 error 'before remove mismatch'
remove tempAlias
let removed = false
try { tempAlias 1 } catch e { removed = true }
assert removed == true error 'remove mismatch'

禁用 Alias​

alias toggleAlias <String val> -> String {
'enabled: ' .. val
}
assert (toggleAlias 'test') == 'enabled: test' error 'before disable mismatch'
disable toggleAlias
let disabled = false
try { toggleAlias 'test' } catch e { disabled = true }
assert disabled == true error 'disable mismatch'
enable toggleAlias
assert (toggleAlias 'test') == 'enabled: test' error 'enable mismatch'

remove、disable、enable 的目标为别名名称,不附带参数形态。

7. 示例代码​

alias repeat3 <Number times> times <Stack stack> -> {
for { let i = 0 } i < times { i ++ } {
call stack.run
}
}
let repeatCount = 0
repeat3 3 times {
repeatCount = repeatCount + 1
}
assert repeatCount == 3 error 'repeat mismatch'
alias greet <String name> with <String? greeting> -> String {
(greeting ?? 'Hello') .. ', ' .. name .. '!'
}
assert (greet 'Alice' with 'Hello') == 'Hello, Alice!' error 'greet mismatch'
assert (greet 'Bob' with 'Hi') == 'Hi, Bob!' error 'greet with mismatch'
alias <Number num> squared -> Number {
num * num
}
alias <Number num> cubed -> Number {
num * num * num
}
assert (5 squared) == 25 error 'squared mismatch'
assert (3 cubed) == 27 error 'cubed mismatch'
alias choose <Boolean c> between <Value a> and <Value b> -> Value {
c ? a : b
}
assert (choose true between 'Yes' and 'No') == 'Yes' error 'choose mismatch'
const numbers = [1, 2, 3, 4, 5]
const double = alias <Number x> -> Number { x * 2 }
let doubledTotal = 0
each n in numbers {
const d = call double [n]
doubledTotal = doubledTotal + d
}
assert doubledTotal == 30 error 'each alias mismatch'

下一步​