Skill 语言语法基础

1 Skill 的语言特征

Skill 是一门高级交互编程语言,基于 Lisp 语言开发,同时也支持类 C 语言语法,但是不建议使用类 C 风格写法,有些地方用 C 风格的很别捏。发展至今,Skill 不仅支持函数式编程,还支持命令式编程,而且面向对象编程也是作了支持。

1.1 程序即数据

这是 Skill 最重要的一个特征,在 Skill 中程序和数据一样被表示为列表,所以它们就像数据一样可以被操作。我们可以动态地创建或修改列表,比如一个函数可以反复被重定义,进而影响到使用这个函数的地方,这种"程序即数据"的概念使得 Skill 可以用来编写灵活的应用程序。

1.2 Skill 的表达式

既然程序即数据,那它们就一定得有共同的表示形式,在 Skill 中也称作 S 表达式,有两种:

  • 原子

原子是一个单独的值,可以是数字、字符串、符号等,比如

ini 复制代码
123         ;数字
"hello"     ;字符串
Symbol      ;符号
  • 列表

列表是由一对圆括号包围的一系列表达式,其中第一个元素通常是函数或宏的名字,后面的元素是函数的参数。列表元素间用空格隔开。列表可以彼此嵌套使用,这也是 Skill 灵活语法的直观体现。

scss 复制代码
(list 1 2 3)        ; 创建列表 (1 2 3)
(cons 1 (list 2 3)) ; 创建列表 (1 2 3)

在上面这段代码里,list 是一个函数名称,用于创建列表;cons 也是一个函数,用来连接两个列表。

1.3 Skill 的函数调用

在 Skill 中可以像 C 语言那样调用函数,也可以使用 Skill 的 S 表达式形式。例如现在有一个函数 add,接收两个数字返回相加后的结果。

  • C语言风格
scss 复制代码
 add(1 5)  ; 返回6  
  • S 表达式风格
csharp 复制代码
(add 1 5)    ; 返回6

Skill 中,函数默认返回函数体中最后一个表达式的值,如果最后一个表达式无返回值,则返回 nil,nil 表示空值。

2 特殊符号

Skill 中有一些符合具有特殊函数,且不同于常见的语言(如 C 和 Java)。

2.1 括号 ()

在 Skill 中括号代表一个列表表达式,要求第一个参数是函数,所以不能像在 C 语言里面那样随意加。如下图所示,我们给数字 1 加括号,就会报错。

给数字 1 加括号

如果想使用括号定义列表,除了使用 list 函数外,还可以使用单引号 '。

scss 复制代码
'(1 2 3)    ; 创建列表 (1 2 3)

2.2 单引号 '

Skill 中的单引号有使用原本值的意思,类似于引用的感觉。可用于创建列表及创建符号变量以及引用函数。比如

ini 复制代码
'a    ; 创建符合 a
'abc  ; 创建符合 abc
(fboundp 'add)  ; 这里的单引号就是引用函数 add 的意思

2.3 分号 ;

分号用于单行注释,我在之前已经有使用过,多行注释的形式则跟其他语言类似,使用 /* ... */ 的形式。

2.4 空格

空格用于Skill 中的元素分割。

2.5 大括号 {}

大括号把多个表达式组合成一个表达式,返回值是最后一个表达式的返回值,可以减少不必要的返回值。如图所示,下面的代码只有一个返回值 5。

大括号的使用

2.6 t

t 表示布尔值 true,false 使用 nil。此外,所有的非 nil 值都会被认为是 true,尤其要注意 0 也是 true,这与 C++ 中很不同。

2.7 中括号 []

中括号用于数组的下标访问。

3 变量及变量类型

前文我们多次提到符号、变量之类的词,这里就说说 Skill 中的变量。

变量在 Skill 中叫做 Symbol,是动态类型,使用前不需要先声明,跟 python 很像。

Skill 中的变量默认是全局变量,局部变量需要特别声明,尤其要注意这点,否则很容易改变全局变量的值,造成逻辑错误。

3.1 变量类型

  • 符号 symbol

symbol 既是刚刚说到的变量,又代表一种数据类型,类似 char 类型的变量。

第一次 a 的类型是 symbol

  • 字符串 string

是的,就是我们熟知的字符串,无需多言。

  • 整数 integer

整数。

  • 浮点数 float

浮点数。

  • 列表 list

列表是一种数据结构,也可以说是一种变量类型,这里我们就傻傻不分清,在 Skill 中连程序都是数据,数据结构其实没那么严格。

使用 list 函数或者单引号创建列表。列表对元素个数、元素类型没有限制,可以任意嵌套。要注意,使用单引号定义 list 时,不会对内部的表达式进行展开求值。

使用单引号 ' 定义list

还可以使用冒号定义只有两个元素的 list,常用于定义坐标。

ini 复制代码
 a = ( 1 : 4 )    ;定义列表 (1 4)
  • 数组 array

使用 declare 定义数组:

ini 复制代码
(declare week[7])    ; 定义一个含7个元素的数组

数组元素使用 [] 的形式进行访问,下标从 0 开始。数组可以直接使用等会赋值,是浅拷贝。

  • 关联表 Association Tables

以 key/value 的形式保存的数据的集合,key 的类型没有限制,可以是任意类型。使用 makeTable 函数创建一个table:

ini 复制代码
myTable = (makeTable "table1" 0)

"table1"是表名,并不是变量名称,0 表示从表中查不到 key 时返回 0。

3.2 局部变量

  • 使用 let 定义局部变量

不声明初始值的格式如下,定义了 a,b 两个局部变量。

使用 let 定义局部变量

声明初始值的格式,如下,局部变量 a 的初始值是 7,b 的初始值是 5.

使用 let 定义局部变量并赋初始值

  • 使用 prog 定义局部变量

prog 增加了对 return 和 go 的支持,要注意,prog 和 循环一起使用时,return 始终是返回到 prog 的外围,prog 没有赋初始值的语法。

3.3 局部变量的特性

局部变量能穿透到函数内部,就跟全局变量一样。

下图定义了两个函数 trOne 和 trTwo,trOne 先定义了局部变量 aGlobal 然后调用了函数 trTwo;trTwo 函数第一行会打印 aGlobal 的值。

局部变量穿透到函数内部

如果我们调用 trOne,发现内部的 trTwo 函数里第一行的 aGlobal 是 trOne 里定义的局部变量,值为 5;如果我们在 trOne 外面直接调用 trTwo,此时访问的是全局变量 aGlobal。

相关推荐
lvbu_2024war0113 分钟前
MATLAB语言的网络编程
开发语言·后端·golang
问道飞鱼14 分钟前
【Springboot知识】Springboot进阶-实现CAS完整流程
java·spring boot·后端·cas
章章小鱼15 分钟前
LLM预训练recipe — 摘要版
人工智能
Q_192849990633 分钟前
基于Spring Boot的电影网站系统
java·spring boot·后端
豌豆花下猫1 小时前
Python 潮流周刊#83:uv 的使用技巧(摘要)
后端·python·ai
算家云1 小时前
Stability AI 新一代AI绘画模型:StableCascade 本地部署教程
人工智能·ai作画·stable diffusion·模型构建·算家云·算力租赁·stablecascade
凡人的AI工具箱1 小时前
每天40分玩转Django:Django部署概述
开发语言·数据库·后端·python·django
RacheV+TNY2642781 小时前
深度解析:电商平台API接口的安全挑战与应对策略
人工智能·python·自动化·api
学术会议1 小时前
“智能控制的新纪元:2025年机器学习与控制工程国际会议引领变革
大数据·人工智能·科技·计算机网络·机器学习·区块链
SomeB1oody1 小时前
【Rust自学】7.2. 路径(Path)Pt.1:相对路径、绝对路径与pub关键字
开发语言·后端·rust