# CAIE_Code **Repository Path**: ibenzhou/CAIE_Code ## Basic Information - **Project Name**: CAIE_Code - **Description**: Pseudocode translator based on CAIE A Level Pseudocode cloned from http://github.com/iewnfod/CAIE_Code - **Primary Language**: Python - **License**: MPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-11-15 - **Last Updated**: 2024-11-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # CAIE Code (cpc)

logo

CAIE 伪代码解释器

中文 | English

## 安装与使用 > [在线版本](https://github.com/createchstudio/caie-code-environment) ### 安装前提 1. `Python3` 环境 *推荐使用 PyPy3 以获得更好的性能* 2. `git` 指令 > macOS用户请安装`Command Line Tools for Xcode` 3. `cargo`命令 ### 正式安装 0. 对于 macOS 用户,可使用以下脚本一键安装: ```shell curl -fsSL https://atcrea.tech/cpc.sh | sh ``` *对于其他用户...* 1. 克隆此项目 ```git clone https://github.com/iewnfod/CAIE_Code.git``` 2. 进入项目 ```cd CAIE_Code``` 3. 运行 * 二进制文件存在于`bin`中,请将自己系统对应的二进制文件加入到`PATH`中 * `MacOS`若无法正常运行其中的二进制文件,可尝试自己编译 [`build.sh`](./build.sh) * `Windows`若无法正常运行,也可尝试自己编译 [`build.ps1`](./build.ps1) >若运行已有二进制文件后无反应,同上。若依旧无法解决,请提交issue * 如果需要使用`man`指令,请自行将[cpc.1](./man/cpc.1)硬链接到你的`MANPATH`内,以便更新后不必再次链接。 * `Linux`用户可以使用以下指令: ``` sudo ln -f ./man/cpc.1 /your/man/path ``` * `Windows`用户请自行搜索 ### 更新 * 如果您是完全使用以上步骤进行安装的,您可以使用`cpc -u`快速更新 * 在`dc0cd71`之后引入自动更新功能,每周自动检测一次更新,可由选项配置 * 如果您并没有使用`git`进行安装,您需要手动下载新的版本,并使用和您之前相同的方法安装 ## 用法 ``` cpc [file_paths] [options] ``` ### 选项 | Mnemonic | Option | Description | | -------- | ------ | ----------- | | `-c` | `--config` | 对解释器进行设置 | | `-d` | `--document` | 使用系统默认方式打开官方规范文件 | | `-h` | `--help` | 显示帮助页面 | | `-k` | `--keywords` | 显示所有的关键字 | | `-m` | `--migrate` | 将一个目录中的所有 `.p` 文件切换为 `.cpc` | | `-n` | `--notification` | 显示由开发者发布的未过期通知 | | `-p` | `--parse` | 显示所有解析的信息 | | `-t` | `--time` | 显示运行脚本花费的时间 | | `-u` | `--update` | 更新此解释器的版本 | | `-v` | `--version` | 显示解释器当前版本 | | `-gt` | `--get-tree` | 显示脚本解析后生成的可运行的树 | | `-lc` | `--list-configs` | 显示解释器的所有设置 | | `-ne` | `--no-error` | 禁止所有错误的输出 | | `-rc` | `--reset-configs` | 删除解释器的所有设置 | | `-init` | `--init-requirements` | 安装所有的依赖 | ### 可选配置 - `remote` - `github`:使用 GitHub 作为更新源并始终保持最新。 - `gitee`: 使用 Gitee 作为更新源。(此源可能比 Github 要慢) - `branch` - `stable`:更新较慢,但最稳定。 - `nightly`:此分支每天更新一次。早期用户可以试用此分支,请积极报告问题。 - `dev`:最新版本的 CPC,可能包含许多未经测试的功能。 > 此设置需要运行一次 `cpc -u` 才能生效。 > 在开发者模式中,您的远程配置不会被更改,分支将被锁定在 `dev`。 - `auto-update` - `true`:启用自动更新。 - `false`:关闭自动更新。 - `last-auto-update` 接受所有非负实数,由系统自动更新。 - `interval-update` 接受所有非负整数,单位秒,作为自动更新间隔。 - `recursion-limit(rl)` 接受所有整数,作为解释器的递归深度限制。 - `dev` - `true`: 启用开发者模式。 - `false`: 关闭开发者模式。 - `integrity-protection` - `true`: 启用完整性保护。 - `false`: 禁用完整性保护。 > 完整性保护将会阻止任何意外或恶意的解释器修改。 > 此保护将在开发者模式下被自动禁用。 - 开发者选项 - `dev.simulate-update` - `true`: 开启模拟更新 - `false`: 关闭模拟更新 ## 常见问题 ### 出现 `Import Error` 尝试手动安装依赖: ```shell pip install -r requirements.txt ``` ### 成功执行了第四步的依赖安装但还是无法正常运行 `cpc`文件会优先选择 `PyPy3` 运行 因此,在安装依赖时,请确保安装在了正确版本的 `Python3` 上 可以使用 `<指定Python版本> -m pip install -r requirements.txt` 进行安装 ### Playground 模式下,上下左右键无法正常使用 使用 `pip install readline` 安装依赖并尝试运行 若 `readline` 无法正常安装,请安装 `gnureadline`,即 `pip install gnureadline`,再尝试运行 ### cpc在启动时报OSError 进入`cpc`安装目录,可使用 删除`.cpc_history`文件 更新`cpc` ```shell cd $(which cpc)/../.. rm -rf .cpc_history cpc -u ``` *若依旧无法解决问题,请提交issue* ## 效率测试 ### 测试环境: * 机型: 2020 Macbook Pro (A2338) * 处理器: Apple M1 * 内存: 8GB * 核心: 8个 (4能效,4性能) * 系统版本: macOS 14.1.1 (23B81) * Python 版本: PyPy 3.9.16 ### 基础测试 * 赋值: 1200w/s ``` DECLARE a : INTEGER FOR i <- 1 TO 12000000 a <- i NEXT i ``` * 显式转换+赋值: 760w/s ``` DECLARE a : STRING FOR i <- 1 TO 7600000 a <- STRING(i) NEXT i ``` * 隐式转换+赋值: 1000w/s ``` DECLARE a : STRING FOR i <- 1 TO 10000000 a <- i NEXT i ``` * 输出: 65w/s ``` FOR i <- 1 TO 650000 OUTPUT i NEXT i ``` ### 常见运算测试 * [随机生成10w数据+希尔排序](test/sort_test.cpc):3.5s 左右 ## 标准 ### 基本标准 * 推荐使用驼峰命名法 * 源文件后缀名推荐使用 **.cpc**(CAIE Pseudo Code 的首字母简写) * 源文件推荐使用 **utf-8** 编码 * 所有保留字均为大写,并且程序有大小写区分 * 使用 `//` 进行注释 ### 一些特性 ~~(说实话就是我不想改了,也有可能是没想到什么好方法来改)~~ * 使用保留字以实现子空间 ~~(虽然官方文档要求有缩进,但是在此不做强制要求)~~ * 由于没有进行缩进的识别,`CASE`中的每一项末尾都需要添加`;`表达这一项结束了 ### 基础数据类型 * `INTEGER` 整型 (`0`) ``` 1 2 123 -123 ``` * `REAL` 浮点型 (`0.0`) ``` 1.1 0.1 -12.1233 ``` * `CHAR` 单个字符 (`''`) ``` '1' '!' 'd' ``` * `STRING` 字符串 (`""`) ``` "Hello" "World" "!" ``` * `BOOLEAN` 布尔值 (`FALSE`) ``` TRUE FALSE ``` * `DATE` 日期 (当前日期) ``` 25/07/2023 10/12/2012 ``` * `None` 此类型表示未知的类型,无法通过常规方法声明,也不应该滥用,仅会作为某些特殊函数的返回值存在 ### 语法定义 1. 变量与常量 * 变量声明 ``` DECLARE : DECLARE : ARRAY [:, ...] OF ``` * 常量声明 ``` CONSTANT = ``` * 赋值 ``` <- [, ...] <- ``` 2. 输入与输出 * 输入 ``` INPUT ``` * 输出 ``` OUTPUT , ... ``` 3. 操作符 * `+` 加法 * `-` 减法 * `*` 乘法 * `/` 除法 * `>` 大于 * `>=` 大于等于 * `<` 小于 * `<=` 小于等于 * `=` 等于 * `<>` 不等于 * `&` 字符串拼接 * `MOD` 取模 * `DIV` 整除 4. 逻辑运算 * `AND` 与 * `OR` 或 * `NOT` 否 5. 条件语句 * IF 语句 ``` IF THEN ENDIF IF THEN ELSE ENDIF ``` * CASE 语句 此处官方语法中并没有分号`;` ``` CASE OF : ; : ; ... OTHERWISE : ; ENDCASE ``` 6. 循环语句 * FOR 循环 ``` FOR <- TO NEXT ``` * REPEAT 循环 ``` REPEAT UNTIL ``` * WHILE 循环 ``` WHILE ENDWHILE 7. 函数 * 无返回值函数定义 ``` PROCEDURE () ENDPROCEDURE PROCEDURE ( : , ...) ENDPROCEDURE ``` * 无返回值函数调用 ``` CALL () CALL (, ...) ``` * 有返回值函数定义 ``` FUNCTION RETURNS RETURN ENDFUNCTION FUNCTION ( : , ...) RETURNS RETURN ENDFUNCTION * 有返回值函数调用 ``` () (, ...) ``` * 在定义函数的每个参数前,都可以使用 `BYREF` 或是 `BYVAL` 声明是需要引用还是复制。若一个参数前没有声明传入方式,会向上一个参数靠齐。在没有全部都没有声明,或者没有前一个参数可供参考时,默认的传入方式为 `BYVAL`。 * 在 `BYVAL` 中,如果确定了数组的类型,隐式转换将会发生,但在 `BYREF` 中,并不会考虑数组类型 * `BYREF` : 引用变量,在函数内修改后,函数外变量的本体的值也会修改 * `BYVAL` : 复制变量的值,在函数内做出的任何修改都不会影响到传入的变量本体 8. 文件读写 * 打开文件 ``` OPENFILE FOR ``` * 读取文件 ``` READFILE , ``` * 写入文件 ``` WRITEFILE , ``` * 关闭文件 ``` CLOSEFILE ``` * 定位读取 ``` SEEK ,
``` * File Mode 1. `READ` 2. `WRITE` 3. `APPEND` 4. `RANDOM` 9. 自定义类型 * 枚举类型 ``` TYPE = (, ...) ``` * 类型指针 ``` TYPE = ^ ``` * 自定义 (注意: **若将一个类的实例`a`赋值给另一个实例`b`,此时不会检查类型,且`b`会成为`a`的引用**) ``` TYPE ENDTYPE ``` 10. 面对对象 * 定义对象 ``` CLASS PUBLIC PROCEDURE NEW () ENDPROCEDURE ENDCLASS ``` * 私有/公有变量 ``` PRIVATE : PUBLIC : ``` * 私有/公有函数 ``` PRIVATE PROCEDURE () ENDPROCEDURE PUBLIC PROCEDURE () ENDPROCEDURE PRIVATE FUNCTION () RETURNS ENDFUNCTION PUBLIC FUNCTION () RETURNS ENDFUNCTION ``` * 创建实例 ``` NEW () ``` > 若不标明变量或函数的访问权限,默认为公有 11. 由此解释器提供的特殊语法 * DELETE 删除变量或常量 ``` DELETE ``` * PASS 跳过 (即不执行任何操作) ``` PASS ``` * IMPORT 导入文件 ``` IMPORT ``` > 此处的`expression`通常为一个被双引号包裹的字符串 > 导入操作并不会做任何隔离,也就是说,被导入的文件的所有内容都会完全暴露给当前文件,因此请注意变量名重复使用的问题 > 因此推荐使用[`Import`](./scripts/import.cpc)函数进行导入操作 ``` CONSTANT = Import("") ``` ### 内置函数 * `LEFT(ThisString : STRING, x : INTEGER) RETURNS STRING` ``` $ LEFT("ABCDEFGH", 3) "ABC" ``` * `RIGHT(ThisString : STRING, x : INTEGER) RETURNS STRING` ``` $ RIGHT("ABCDEFGH", 3) "FGH" ``` * `LENGTH(ThisString : STRING) RETURNS INTEGER` ``` $ LENGTH("Happy Days") 10 ``` * `MID(ThisString : STRING, x : INTEGER, y : INTEGER) RETURNS STRING` ``` $ MID("ABCDEFGH", 2, 3) "BCD" ``` * `LCASE(ThisChar : CHAR) RETURNS CHAR` > 从2023年开始弃用 ``` $ LCASE('W') 'w' ``` * `UCASE(ThisChar : CHAR) RETURNS CHAR` > 从2023年开始弃用 ``` $ UCASE('h') 'H' ``` * `TO_UPPER(x : ) RETURNS ` > 可以是 `CAHR` 或者 `STRING` ``` $ TO_UPPER("hello") "HELLO" $ TO_UPPER('a') 'A' ``` * `TO_LOWER(x : ) RETURNS ` > 可以是 `CAHR` 或者 `STRING` ``` $ TO_LOWER("HELLO") "hello" $ TO_LOWER('A') 'a' ``` * `INT(x : REAL) RETURNS INTEGER` ``` $ INT(27.5415) 27 ``` * `RAND(x : INTEGER) RETURNS REAL` ``` $ RAND(87) 35.43 ``` * `EOF(file_path : STRING) RETURNS BOOLEAN` * `POW(x: REAL, y: REAL) RETURNS REAL` * `DAY(ThisDate : DATE) RETURNS INTEGER` ``` $ DAY(25/07/2023) 25 ``` * `MONTH(ThisDate : DATE) RETURNS INTEGER` ``` $ MONTH(25/07/2023) 7 ``` * `YEAR(ThisDate : DATE) RETURNS INTEGER` ``` $ YEAR(12/12/2005) 2005 ``` * `DAYINDEX(ThisDate : DATE) RETURNS INTEGER` > 周日返回1,周一返回2,以此类推 ``` $ DAYINDEX(25/03/2024) 2 ``` * `SETDATE(day : INTEGER, month : INTEGER, year : INTEGER) RETURNS DATE` ``` $ SETDATE(25, 03, 2024) 25/03/2024 ``` * `TODAY() RETURNS DATE` ``` $ TODAY() 25/03/2024 ``` **(以下方法均不属于CAIE提供的标准方法)** * `EXIT(code : INTEGER)` 以code为退出码,退出程序 (若不填写code,则默认为0) * `ROUND(x : REAL, decimalPlace : INTEGER)` decimalPlace不填写默认为0 * `PYTHON(code: STRING)` Python3代码运行接口,并会返回code的运行结果,由于两个语言的类型系统并不互通,其返回的所有结果的类型皆为None,可赋值给任何本语言类型但不保证是否能够获得预期的结果 * ***若需要获得此接口的返回值,请将返回值赋值给名为`_result`的变量,否则将会返回值为None的None类型*** * ***若需要向此接口内传入变量,请在Python3代码中使用与外部相同的变量名,并将那个变量作为参数传入此函数*** ``` > DECLARE a : INTEGER > PYTHON("_result=a+1", a) 1 ``` * `VARTYPE(v)` 获取`v`的数据类型并以字符串的形式返回 * `ANY` 这是一个任意类型用于允许一些未知类型的输入 * 更多非官方内置函数,请查阅 [scripts](./scripts) ## 目标 ### Version 0.1.x 目标 - [ ] 实现所有由[官方文档](./Pseudocode%20Guide%20for%20Teachers.pdf)规定的功能 - [ ] 提高运行的稳定性,使得整体达到一个相对可用的状态 ### Version 0.2.x 目标 - [ ] 对核心进行大规模更新与优化 - [ ] 支持编译到高性能虚拟机 (也就是类似于Java的解决方法) ### Version 0.3.x 目标 - [ ] 支持直接编译为可执行文件 ### 长期目标 - [ ] 提供更多包 - [ ] 提高运行速度与效率 - [ ] 实现自举 ## 赞助商 1Password ## 作者与贡献者