互动小说技术基金会版权所有2020-24。本文件根据Creative Commons Attribution-ShareAlike 4.0国际许可.
格雷厄姆·纳尔逊通知6是一个用于创建冒险游戏的系统,并且Inform设计师手册是一本关于它的书。
2001年出版的该手册第四版就是从这一主张开始的。这仍然是事实——尽管这些天我们必须明确说明这是关于Inform的6(通知7是一个更现代的系统,与之截然不同,有自己的手册用信息写作.)
自DM4发布以来的二十年里,Inform 6基本保持不变。虽然一些作者继续直接使用I6,但它的主要用途是作为Inform 7编译器的中间阶段。因此,稳定性和可靠性一直是I6维护者的口号。
然而,语言并没有完全保持静止。最值得注意的是,编译器现在支持Glulx VM以及原始的Z机器。这需要对语言和编译器进行一些添加。该系统的其他部分已经过优化和重新安排,目的是使Inform成为两个目标平台上更灵活的工具。
因此,DM4现在有点过时了。本文档旨在为今天的Inform 6用户填补空白。
I6版本历史
这是I6版本及其最重要功能的高级视图。有关每个版本的完整描述,请参阅I6发行说明(旧笔记在这里).
- 6.21(1999年4月):DM4版本。
- 6.30(2004年2月):Glulx支持;
!%
标题注释;首都(A)
打印令牌。
- 6.31(2006年2月):错误修复。
- 6.32(2010年11月):
@推动
,@拉力
装配宏;支持所有Glulx操作码;Glulx浮点常量。
- 6.33(2014年5月):UTF-8源文件;
$OMIT_UNUSED_ROUTINES(未使用_概述)
;<吃馅饼,兽人>
;取消引用
指令;字典
用于设置单词标志的指令。
- 6.34(2020年5月):恢复v3支持;
原始数据源
指令;改进更换
指令。
- 6.35(2021年5月):Unix风格的命令行选项;命令行选项定义数值常量。
- 6.36(2022年1月):大多数内存限制都没有了;一些编译时类型检查。
- 6.40(2022年7月):简化了司令部的论点;删除了模块和临时文件编译;无代码剥离。
- 6.41(2022年7月):错误修复。
- 6.42(2024年2月):无限标识符长度;无限缩写长度;内联字节程序集。
- 6.43(未发布):单一(
//秒
)dict标志和$DICT_IMPLICIT_SINGULAR($DICT_隐含_单一)
; 截断dict标志和$DICT_TRUNCATE_FLAG($DICT_RUNCATE_FLAG)
;$语法_元数据_语法
;$语法_版本
语法版本3(实验)。
语言与图书馆
本附录涵盖了Inform 6语言和编译器的更新。还包括一些勘误表。
此处描述的更改主要针对DM4第1-7、36和38章及以上。(“§1”等章节参考指DM4章节.)中间章节(DM4的大部分)涉及Inform 6库,它是不包含在本文件中。
DM4描述的Inform库是版本6/9于1999年4月与Inform 6.21一起发布。库随后更新为6/10(bug-fix版本)然后6/11(Glulx支持和一些附加功能)通知7发展。
Inform库现在是由David Griffith管理的单独项目。可以在上找到更新项目页面.
Inform 6编译器可以通过通知5家图书馆。还存在许多替代的Inform库,例如地铁84和双关语信息(支持非常旧的计算机)和鸭嘴兽(重新设计的图书馆)。Inform 6编译器应该可以与所有编译器一起使用。
编译器选项和设置
Inform编译器有许多选项来控制其编译行为。这些选项有三种样式,有三种提供方式。
提供选项
所有选项都可以通过三种方式提供给编译器(§39):
- 作为命令行参数
- 在单独的文件中,用指定
(文件.icl)
或--配置文件.icl
- 在第一个源文件的开头,在以开头的注释中
!%
第三种方法是自DM4以来的新方法。它允许您将游戏的编译选项存储在与其源代码相同的文件中。
例如,此源文件将以Glulx格式编译,搜索i6lib
包含文件的目录,提高动词的最大数量,并显示编译统计信息:
!% -G公司!% -秒!% +include_path=i6lib!% $最大值=255包括“Parser”;包括“VerbLib”;[初始化;location=厨房;];目标厨房“厨房”描述为“这是厨房。”,有光;包括“语法”;
使用指定的选项!%
必须位于开始源文件之前或之间没有空白行或其他注释。
请注意,在设置源代码之前会对文件的这一部分进行解析。(实际上,此部分可以指定源编码!)因此,此部分中的选项必须是纯ASCII。
!%
选项优先于命令行选项。命令行选项按顺序读取;以后的选项(包括(文件.icl)
包含)优先于早期包含。
开关选项(破折号)
经典选项以破折号开始,这是命令行工具的传统样式。例如-小时
选项(help)显示了一页输出,记录了如何运行编译器。-氢气
将显示一个页面,列出以破折号开头的所有选项(§表3)。
自DM4以来的新功能:
-a2类
:从6.40开始,这将显示函数的汇编编码(如-一个
)加上程序集操作码的字节编码。(在6.40之前,这是-t吨
选项。)另请参见$!ASM公司
跟踪选项。
-B类
:仅在Z代码版本6和7中,对例程和字符串的压缩地址使用不同的偏移值。在这种模式下,字符串通过具有奇数(压缩)地址来区分,而例程是偶数。这允许游戏文件包含更多可执行代码。(默认值为-~B个
,其中例程和字符串段使用相同的偏移值,因此字符串和例程的值具有不同的范围。)
-铜
:将源文件视为UTF-8(Unicode)编码。
-G公司
:编译为Glulx格式而不是Z-machine格式。默认输出文件将被赋予.ulx文件
扩展。
-G-vX。Y.Z(Y.Z)
:在Glulx中,指定要在生成的游戏文件中记录的VM版本号。例如,-G-v3.1.0
将生成一个指定VM规范3.1.0的游戏文件。
-H(H)
:在Glulx格式中,使用Huffman编码压缩字符串。这是默认值;要使用未压缩的文本,请使用-~小时
.
-k个
:将调试信息输出到文件游戏信息.dbg
此开关记录在DM4(§7)中,但输出格式已更改。从6.33开始,它是一种极其冗长的XML格式;看见在下面此外,从6.35开始-k个
开关不再自动设置-D类
.
-第三组
:跟踪对所有函数的调用。DM4文件-g2型
这样做,但从6.21开始,-第二组
不跟踪单板功能。截至6.35,-第三组
追踪一切。另请参见$!运行时间
跟踪选项。
-W公司
:设置Z代码标题扩展表(Z-spec 1.0)中的字数。默认值为-第3周
. The$ZCODE_HEADER_EXT_订单
setting做同样的事情。
-V(V)
:显示编译器版本并退出,无需进一步操作。
自DM4起删除:
以下交换机选项早于6.40,但现在已不存在。
-F类
:已删除使用临时文件(而不是内存)进行编译数据的功能。
-M(M)
,-单位
,-年
:已删除创建和导入链接器模块的功能。
以下交换机选项早于6.40,但为了支持跟踪选项.
-b条
:自通知5以来,没有做任何事情。
-j个
:替换为$!对象
选项。
-我
:从未完全实施;现有的功能已被$!文件夹
选项。
-米
:替换为$!MEM公司
选项。
-n个
:替换为$!支柱
和$!行动
选项。
-o个
:替换为$!地图
选项。
-第页
:替换为$!MAP=2
选项。
-t吨
:替换为$!ASM=2
选项或-a2类
开关。
路径选项(加号)
以编译器使用的加号集路径开头的选项(§39)。例如,+DIRNAME公司
或+include_path=目录名
设置搜索包含文件的目录。
您还可以提供以逗号分隔的路径列表:+include_path=DIR1、DIR2、DIR3
自DM4以来的新功能:
双加号将向现有列表中添加一个或多个新路径。例如,++include_path=目录名
将DIRNAME添加到搜索包含文件的路径中。将首先搜索新添加的路径。
在命令行上(但不在ICL文件或注释中),也可以以Unix样式指定路径选项。(这是在6.35中添加的。)
--路径路径=目录--addpath路径=目录
自DM4起删除:
这个+模块_路径
和+临时路径
期权自6.40起不再存在。
编译器设置(美元)
这些在DM4中被称为“内存设置”(§39)。然而,它们现在包含了广泛的编译器行为。
这个$列表
该设置将显示一个输出页面,其中列出了Z-machine游戏的所有玩偶设置。要查看Glulx游戏的所有设置,请给出-G公司
前面的参数$列表
.
自DM4以来的新功能:
以哈希符号开头的设置($#
)将在游戏代码中定义任意数字常量。如果未提供任何值,则常数定义为零。这相当于(并与)常量
指令。(在6.35中增加。)
$#符号$#SYMBOL=数字
以感叹号开头的设置($!
)是一个跟踪选项。(在6.40中添加。)它们的格式略有不同;看见跟踪选项,如下所示。
在命令行上(但不在ICL文件或注释中),也可以以Unix样式指定编译器设置。(在6.35中增加)这避免了逃避美元符号的需要。
--列表--opt SETTING=编号--定义SYMBOL=数字--trace TRACEOPT=编号
自6.36起,不再需要以下内部内存设置,且这些设置无效:$分配_ CHUNK_SIZE
,$MAX_OBJECTS(最大值)
,$MAX_等级
,$最大_符号
,最大PROP_TABLE_SIZE
,$最大_INDIV_PROP_TABLE_SIZE
,$最大_OBJ_PROP_COUNT
,$最大_OBJ_PROP_TABLE_SIZE
,$最大_阵列
,$MAX_STATIC_DATA
,$最大_调整
,$MAX_VERBS(最大值)
,$MAX_VERBSPACE
,$最大标签
,$MAX_EXPRESSION_NODES(最大导出代码)
,$最大源文件
,$最大_包含_深度
,$MAX_操作
,$MAX_LINESPACE(最大线间距)
,$最大_ZCODE_SIZE
,$MAX_LINK_DATA_SIZE(最大_链接_大小)
,$MAX_TRANSCRIPT_SIZE(最大_随机_大小)
,$MAX_DICT_入口
,$MAX_NUM_STATIC_STRINGS(最大_最小_状态_字符串)
,$最大代码_字符
,$MAX_STATIC_STRINGS(最大值)
,$MAX_LOW_STRINGS(最大_下限_字符串)
,$MAX_GLOBAL_VARIABLES(最大全局变量)
,$MAX_LOCAL_VARIABLES(最大_位置_变量)
,$最大_QTEXT_SIZE
.
自DM4以来新增或更新的其他设置:
$DICT_CHAR_SIZE($DICT_字符_大小)
字典中一个字符的字节大小。这只在Glulx中有意义。它可以是1(字典字符为一个字节)或4(字典字符是四个字节的单词)。
$DICT_WORD_SIZE($DICT_单词_大小)
字典词条中的字节数。(在Z代码中,这一点无法更改。v3中总是4,V4+中总是6,最多代表6或9个Z字符。)
$DICT_IMPLICIT_SINGULAR($DICT_隐含_单一)
如果这是1,Inform将设置单数(//秒
)未明确标记复数的任何名词的标志(//第页
). (第6.43节增加)
$DICT_TRUNCATE_FLAG($DICT_RUNCATE_FLAG)
如果这是1,Inform为任何被截断的dict单词设置dict标志6;也就是说,如果单词的源定义不适合$DICT_WORD_SIZE($DICT_单词_大小)
(第6.43节增加)
如果该值为0,则为所有动词设置dict标志6(相当于dict标志1)。这是Inform早期版本的遗留行为,但当前没有库代码依赖于它。
$语法_元数据_语法
如果这是1,您可以将单个动作标记为meta(而不是依赖动词dict单词中的标志)。请参见动词
在“指令”,如下所示。
在这种模式下,操作值被排序,以便所有元操作发生在所有非元操作之前。常量#最高meta_action_number
允许您区分它们。(如果没有元操作,则此常量为-1。)
$语法_版本
将语法表格式设置为给定版本。这相当于设置语法_版本
源代码开头的常量。默认值在Z代码中为1,在Glulx中为2;但标准库在这两个平台上都使用版本2。(第6.43节增加)
从6.43开始,Z代码支持新的语法版本3。(请参阅“语法表格式”)这是版本2的一个更紧凑的变体。
$GLULX_OBJECT_EXT_BYTES(美元)
要添加到每个对象表项的额外零字节数。这是游戏可以自由使用的可写内存。(这仅在Glulx中有意义,因为Z代码对象格式由规范固定。)
$indep_PROP_START($个人_启动)
第一个单独属性的索引号。这也决定了公共属性的最大数量。(在Z代码中,这是64,无法更改。)
$LONG_DICT_FLAG_BUG(美元)
如果设置为0,字典标记后缀(参见“字典单词“)以任何长度的文字表示。
如果这是1,如果后缀开始于字典单词长度之后,则忽略后缀。(V4+在第九个字符之后;V3在第六个字符之后,第九个或其他字符$DICT_WORD_SIZE($DICT_单词_大小)
在Glulx中设置为。)默认设置为1。
(第6.42节中增加。在早期版本中,错误始终存在,无法关闭。)
$MAX_ABBREVS(最大值)
经济中可能使用的缩写数量(-e(电子)
)模式。此设置适用于所有版本的Inform,但在6.35中,Z代码的最大值从64提高到96。然而,这与$MAX_DYNAMIC_STRINGS最大
; 请参见下文。
缩写(-u个
)switch现在尝试创建$MAX_ABBREVS(最大值)
缩写,而不是总是创建64个。(截至6.36)
在Glulx中,$MAX_ABBREVS(最大值)
不需要并且没有效果,除非使用-u个
开关。
$MAX_DYNAMIC_STRINGS(最大动态字符串)
字符串变量的数量("@00"
等)允许在游戏中使用。在Z代码中,这可能是0到96之间的任意值。在Z代码中设置此项将自动设置$MAX_ABBREVS(最大值)
到(96-$MAX_DYNAMIC_STRINGS)
,因为这两个功能来自同一组96个Z机器缩写。类似地,设置$MAX_ABBREVS(最大值)
套$MAX_DYNAMIC_STRINGS(最大动态字符串)
到(96-$MAX_ABBREVS)
.
在Glulx中,这两个设置没有连接。您可以使用任意数量的动态字符串。如果使用超过100,则必须设置$MAX_DYNAMIC_STRINGS(最大动态字符串)
设置为更高的值。
(在6.35中增加。在早期版本中,Z代码中有32个字符串变量和64个缩写;Glulx中有64个字符串变量。截至6.36,$MAX_DYNAMIC_STRINGS最大
在Glulx中默认为100,这是最大值。截至6.40,$MAX_DYNAMIC_STRINGS(最大动态字符串)
在Glulx中不受限制,但仍默认为100。)
$MAX_STACK_SIZE(最大包装尺寸)
解释器将为Glulx堆栈保留的内存量。(这仅在Glulx中有意义。)
$内存_MAP_EXTENSION
要添加到编译的游戏文件末尾的额外零字节数。这是游戏可以自由使用的可写内存。(这仅在Glulx中有意义。)
$NUM_ATTR_BYTES($NUM_ATTR_BYTES)
每个对象中用于属性标志的字节数。属性的最大数量为8*数字_文字_字节
(在Glulx中,这必须是4加3的倍数。在Z代码中,此值始终为6,无法更改。)
$OMIT_SYMBOL_表格
如果设置为1,编译器将不会将属性、数组和其他代码元素的名称编译到游戏文件中。这意味着打印(属性)p
语句将打印属性编号而不是名称。运行时错误也会忽略符号名称。
引用符号名称的系统常量在以下情况下不可用$OMIT_SYMBOL_表格
已设置。请参阅“常量".
$OMIT_UNUSED_ROUTINES(未使用_概述)
如果设置为1,编译器将从游戏文件中省略未使用例程的编译代码。(请参见$WARN_UNUSED_ROUTINES(警告_未使用_概述)
.)
$系列
将游戏的序列号设置为给定的六位数。(序列号
指令做同样的事情;参见§38。)
$STRIP_UNREACHABLE_标签
如果设置为1(默认值),作为分支优化的一部分,将消除无法访问的标签。正在尝试跳
到无法访问的标签是编译时错误。
如果设置为0,则任何标签都可以跳
ed-to,以较少优化的代码为代价。
(在6.40中增加。在早期版本中,任何标签都可以跳
截至6.41,向前地 跳
s到标签总是允许的。仅向后跳
s到无法访问的标签可能会导致错误。)
$TRANSCRIPT_FORMAT(格式)
如果设置为0(默认值),则游戏文本.txt
由-对
选项使用经典格式,这是为人类校对者设计的。如果设置为1,则转录本使用一种备用格式,指示每个字符串的使用。这对于要解析转录本的工具可能更有用。
$WARN_UNUSED_ROUTINES(警告_未使用_概述)
如果设置为2,编译器将为游戏文件中从未调用的每个例程显示警告。(这包括仅从未调用的例程调用的例程等)如果设置为1,它将仅警告游戏代码中的函数,而不是库文件中的函数。
$ZCODE_FILE_END_PADDING(添加)
如果将其设置为1(默认值),则游戏文件的长度将为512的倍数。如果不是,它将只填充到压缩地址刻度的倍数(2、4或8,具体取决于版本)。(第6.43节中增加。这仅在Z代码中有意义。)
$ZCODE_HEADER_EXT_订单
这将设置Z代码标题扩展表中的字数。默认值为3。这个-W公司
setting做同样的事情。(见Z规范1.0。这仅在Z代码中有意义。)
$ZCODE_HEADER_FLAGS_3
这是要存储在标题扩展表的标志3字中的值。(见Z规范1.1。这仅在Z代码中有意义。)
$ZCODE_LESS_DICT_DATA
如果设置为1,则每个字典条目将有两个字节的数据,而不是通常的三个字节。(在6.36中增加。这仅在Z代码中有意义。)
使用此开关组,您可能无法参考#dict_par3
。您也可以不使用语法版本1,因为该格式需要使用第三个字节作为介词编号。
$ZCODE_MAX_INLINE_STRING($ZCODE_MAX_INLINE_STRING)
这是在程序集操作码中不能内联字符串文本的长度。默认值为32个字符。(第6.42节中增加。这仅在Z代码中有意义。)
如果增加此值,Inform将更加积极地在打印
声明。这将在编译的游戏文件中节省一些空间。然而,这也可能导致函数过长,从而导致“分支超出范围”编译错误。小心使用。
跟踪选项
这些是特殊的编译器设置,显示有关编译过程的额外信息。其中大多数只对调试编译器本身有用。对作者最有用的选项有简单的切换选项,有文档记录在上面.
跟踪选项都具有以下形式$!TRACEOPT公司
或$!TRACEOPT=编号
.选项$!
它本身将显示所有支持的跟踪选项的列表。
在命令行上(但不在ICL文件或注释中),也可以以Unix样式指定跟踪选项。
--跟踪TRACEOPT--trace TRACEOPT=编号--帮助跟踪
默认情况下,所有跟踪选项都处于禁用状态(级别0)。简单的形式$!TRACEOPT公司
或--跟踪TRACEOPT
将命名选项设置为级别1,该级别显示编译期间(或编译后)的信息。一些跟踪选项支持更高级别的详细程度,以打印更多信息。
从6.40开始,跟踪选项系统是新的。在以前的版本中,大部分信息都可以通过命令行开关或跟踪
指令。
$!行动
显示操作和假操作表。$!动作=2
将按照定义对它们进行命名。
(在6.43之前,唯一的选择是按定义命名,即现在的级别2。在6.40之前,该信息由-n个
开关。)
$!ASM公司(与-一个
)
在编译函数时显示函数的汇编语言编码。$!ASM=2
还将显示程序集操作码的字节编码。$!ASM=3
还将显示分支优化信息。$!ASM=4
将显示更多详细的分支信息。
这个$!ASM公司
跟踪级别可以用跟踪程序集
指令。
(6.40之前-t吨
开关显示程序集和操作码字节,如下所示$!ASM=2
或-a2类
现在做了。)
$!b批次
解决后显示补丁标记。$!BPATCH=2
还将显示正在创建的补丁标记。
(在6.40之前,此信息显示为$!ASM公司
跟踪级别。)
$!DICT公司
游戏完成后显示游戏字典。$!DICT=2
还将显示每个字典条目的字节编码。
这个跟踪字典
指令将在代码中的任何位置显示此信息。
$!出口
编译表达式树时显示它们。$!EXPR=2
和$!EXPR=3
将显示更多详细信息。
这个$!出口
跟踪级别可以用跟踪表达式
指令。
$!文件夹
显示源文件并包含正在打开和关闭的文件。
(6.40之前-我
开关和跟踪线
指令显示了此信息。)
$!FINDABBREVS公司
计算缩写时(-u个
),显示选择决定。$!FINDABBREVS=2
还将显示三个etter-block分数。
(6.40之前-u个
开关总是显示此信息。)
$!FREQ公司(与-(f)
)
使用缩写时(-e(电子)
),显示每个缩写的效率。
$!地图(与-z(z)
)
显示已完成虚拟机的内存映射。$!MAP=2
还将显示每个段占用的VM内存的百分比。
(6.40之前-第页
switch显示了分段百分比。)
$!MEM公司
显示编译器中的内存分配和释放。
(6.40之前-米
开关显示了此信息。)
$!对象
游戏完成后显示对象表。
这个跟踪对象
指令将在代码中的任何位置显示此信息。
(6.40之前-j个
开关显示了此信息。)
$!支柱
按定义显示属性和属性。
(在6.40之前,此信息由-n个
开关。)
$!运行时间(与-克
)
将函数跟踪编译到游戏中。每个调用的游戏函数都会打印一条跟踪消息。$!运行时间=2
还将跟踪库调用;$!运行时间=3
还将跟踪单板调用。
在Glulx模式下,$!运行时间=2
如果未设置输出流,则由于规则簿打印跟踪消息,上述操作将导致Glk错误。
美元!统计(与-秒
)
编译完成后打印游戏统计信息。
$!符号
游戏完成后显示符号表。$!符号=2
还将显示编译器定义的符号。
这个轨迹符号
指令将在代码中的任何位置显示此信息。
$!SYMDEF公司
显示遇到和定义的符号。
$!代币
在对标记进行词法分析时显示标记。$!代币=2
还将显示令牌类型;$!代币=3
也会显示他们的词汇上下文。
这个$!代币
跟踪级别可以在代码中的任何点使用跟踪标记
指令。
$!动词
游戏完成后显示动词语法表。
这个追踪动词
指令将在代码中的任何位置显示此信息。
语言更改
Inform语言本身的一些元素已经更新或扩展。
指令
关于通用指令语法的几点说明:
Inform 6中的指令不区分大小写。这些声明是等效的:
全局变量名称;GLOBAL变量名;全局变量名;
DM4没有说明这一点,但在Inform编译器的每个版本中都是如此,因此我们可以接受它作为语言的一个原则。
指令也可以用#
签名:
#全局变量名;
对于独立指令#
标志是可选的。然而,在例程或对象定义中可以使用一些指令。这允许有条件地编译单独的代码行或对象属性(§38)。这些指令是:
Ifdef、Ifndef、If not、Ivv3、Ifv5、Iftrue、Iffalse、Endif
当这些指令之一出现在例程或对象定义中时#
需要签名。
缩写
截至6.40缩写
指令仅在经济中创建缩写(-e(电子)
)模式。如果-e(电子)
开关不被使用,指令被跳过,并且在游戏的缩写表中没有空间被消耗。
从6.42开始,缩写可以是任意长度。(在早期版本中,它们被限制为64个源文本字符。)
阵列
这个阵列
指令(§2.4)支持四种指定值的方法:
数组arrname-->N;数组arrname-->expr1 expr2。。。exprN;数组arrname-->[expr1 expr2…exprN];数组arrname-->“string”;
第三种形式(带方括号)在DM4中没有记录,但自6.0以来一直受支持。括号之间的表达式可以用可选分号分隔。
这个阵列
指令支持6.30中的新数组类型:
数组arrname缓冲区N;数组arrname缓冲区expr1 expr2。。。exprN;数组arrname缓冲区[expr1 expr2…exprN];数组arrname缓冲区“string”;
这个缓冲器
关键字定义arrname公司
作为混合阵列,其中第一个单词 数组-->0
包含长度(N)和以下N字节 数组->WORDSIZE
,数组->(WORDSIZE+1)
...数组->(WORDSIZE+N-1)
包含指定的表达式值或字符串字符。
所有形式的阵列
指令支持静止的
关键字,在6.34中添加:
数组arrname static->1 2 3 4;数组arrname静态字符串“plugh”;
这个静止的
关键字必须出现在数组类型之前(->
,-->
,一串
,桌子
,或缓冲器
). 它指示数组应该放在非可写内存中。
字典
DM4标记了字典
该指令已过时(§表5),但自6.33起已恢复。它允许您向游戏字典中添加单词并设置可选的字典标志。
字典“word”;字典“单词”val1;字典“单词”val1 val3;
第一种形式只是添加字典中没有的单词。第二种形式还设置目录par1
标记为给定值,或者如果单词已经存在,则按位或将该值标记为该标记。第三种形式还设置了dict_par3
以同样的方式标记。
这些值可以是数字文字或常量。Z代码可以是0-255,Glulx可以是0-65535。
延伸
如果$GRAMMAR_META_FLAG=1
,的延伸
指令支持在语法行级别将操作标记为元:
扩展“加载”*名词->推*“游戏”->还原元;
请参见动词
,如下所示。(第6.43节增加)
全球的
截至6.40=
在定义全局变量的初始值时,符号是可选的。这些声明是等效的:
全局foo=12;全球foo 12;
在早期版本的Inform中全球的
指令也可以用于定义数组。自Inform 6.0以来,此用法已被弃用,但编译器仍然可以识别以下声明:
全局数组-->8;
…以及更古老的形式全球数据
,全球首字母
、和全局initstr
截至6.40,所有这些过时的表格都已删除。使用全球的
对于全局变量和阵列
用于数组。
Ifv3型
DM4中提到这仅用于编译器维护(§表5)。事实上,它是由图书馆使用的,因此值得记录。这是一个条件编译指令,如Iftrue公司
,它在生成Z代码V3时编译代码(仅限)。它相当于:
#Ifdef目标代码;#Iftrue(#version_number==3);! ...代码。。。#Endif;#Endif;
Ifv5型
库也使用了这个命名错误的指令(§表5)。它在构建Z代码V4及更高版本时有条件地编译代码或Glulx公司。因此,它是相反的Ifv3型
(这个令人误解的名称是从早期版本的Inform中遗留下来的。)
导入
这个导入
指令自6.40起不再存在。(这就像链接
用于过时的模块链接功能。)
链接
这个链接
该指令自6.40起不再存在。
低钻柱
这个低钻柱
自(至少)Inform 5以来,该指令一直受支持,但Inform 6中不需要它。因此,它在DM4中被否决并没有记录在案。为了提供信息,我们将在这里进行描述。
低字符串文本“Text”;
在Z代码中,这将在可读存储器(第一个64k)中放置一个编码字符串。文本
定义为常量,其值为(地址/2)
。因此,可以这样打印字符串:
打印(地址)(2*文本);
常量也可以与一串
声明:
字符串14文本;
这会将动态字符串14设置为字符串“文本”
然而,使用字符串文字而不是低钻柱
:
字符串14“文本”;
这个低钻柱
Glulx中不支持指令。
原始数据源
这个原始数据源
指令允许您将源文件的一部分标记为是从另一个文件生成的。(例如,一个Inform 7源文件。)此指令是在6.34中添加的。
Origsource“文件名”;Origsource“Filename”10;Origsource“Filename”10 40;原始数据源;
这声明以下所有行都是从给定的文件名派生而来的。这将在错误消息和调试输出中报告。您可以选择在行中提供行号和字符号(在这些示例中为10和40)。
该声明将持续到下一个原始数据源
指令(但不适用于包含的文件)。第四种形式不带参数,用于清除声明。
财产
从6.36开始,现在可以使用财产
指令:
财产个人专有名称;
这给了我们总共四种形式的指令:
属性[附加]名称;属性[additive]name defaultexpr;属性[additive]名称别名oldname;物业个人名称;
请注意,单个属性不能添加剂
,具有默认值,或别名
另一个属性。
这个长的
关键字可以应用于任何财产
指令,但除弃用警告外,它没有任何作用。(所有属性都已长的
,也就是说单词大小,因为Inform 5。)
从6.36开始,可以声明一个名为长的
,添加剂
,或个人
,尽管这些是财产
指令。
! 这声明了一个名为“long”的附加公共属性,默认值为12。性能添加剂长12;
关于Z代码限制,DM4表示:
只有62个[通用属性]可用,其中编译器使用3个,库使用47个。
这句话措辞不当。Z机器(V4+)允许63个常见属性(编号为1到63)。编译器定义了三个:名称
属性加上两个内部使用的隐藏属性。所以游戏和图书馆可能会宣布60更多它们之间的共同属性。
更换
这个更换
指令(§25)允许您重新定义已经定义的函数(例如在库或面板中)。
这个更换
指令有两种形式,其中第二种是在6.33中添加的:
替换Func;替换Func OriginalFunc;
多种定义Func()
可以遵循更换
指令。功能
将引用最新定义的版本,但普通文件中的定义优先于中的定义系统文件(_F)
锉刀或木皮。第二种形式,原始功能
将参考第一-定义的函数版本。
开关
截至6.40开关
指令已过时,并生成弃用警告。使用!%
而不是页眉注释。
这一直被记录为“在源代码的最开始”(§39)。然而,这只是执行力度不够;编译器只检查在定义第一个常量之前是否使用了它。从6.40开始,它只能在定义第一个常量或例程之前使用。
跟踪
这个跟踪
指令允许您在编译期间调整各种跟踪设置和显示信息。从6.40开始,它被弃用为跟踪选项.
在6.36之前,它仅限于几种跟踪信息,其语法相当特殊。截至6.40,它仍然是有限的,但其语法更加一致。
这个跟踪
该指令有两种风格。
跟踪字典跟踪对象轨迹符号追踪动词
每个都打印指定的数据表截至编译时。等效跟踪选项($!DICT公司
,$!对象
,美元!符号
,$!动词
)编译完成后打印命名表。
(为了与跟踪选项系统保持一致,这四行可以采用可选数字。这只对轨迹符号2
,比如$!符号=2
,打印更多符号信息。)
轨迹集合[val]跟踪表达式[val]跟踪令牌[val]
每个选项都会调整等效命名跟踪选项的级别($!ASM公司
,$!出口
,$!代币
). 可选值可以是远离的
(0),在
(1) ,或任何数字。如果未给定值,则设置选项在
(1).
跟踪[val]
相当于轨迹集合[val]
.
跟踪线[val]跟踪链接器[val]
跟踪线
旨在支持从未实现的线路追踪功能。跟踪链接器
支持不再存在的模块链接功能。这些选项现在不起任何作用。
取消引用
这个取消引用
指令允许您删除先前定义的常量。该指令在6.33中添加。
取消定义Const;
这就留下了施工
符号未定义。如果施工
从未定义,这无济于事。
动词
截至6.43,我们接受同一动词的两个动词定义:
动词“take”*“库存”->库存*名词->Take;动词“take”*“注释”->WriteNote;
这相当于延长最后一个
宣言:
将“take”延长到最后*“注释”->WriteNote;
这个延伸
首选表单,因此这样做会显示警告。
如果$GRAMMAR_META_FLAG=1
,的动词
指令支持在语法行级别将操作标记为元:
动词“load”*名词->推*“游戏”->还原元;
这允许单个动词同时具有元动作语法和非元动作语法。要区分这些,请将动作值与#最高meta_action_number
(第6.43节增加)
(延伸
指令也可以用这种方式将动作标记为元。)
仍然支持旧语法:
动词元“score”*->分数*“完整”->FullScore;
这隐式地将所有命名操作标记为meta。(它还标记了动词dict单词meta,这是传统用法。)
版本
这个版本
DM4中提到该指令已过时(§表5)。从6.40开始,它会生成一个弃用警告。使用-第3版
命令行开关或!% -第3版
而不是页眉注释。
从6.36开始,此指令只能在定义第一个例程之前使用。(此限制减少了但没有消除各种代码生成错误。)
声明
<
行动>
行动声明<操作>
和<<行动>>
(§6)现在最多支持四个论点。这个演员
从6.33开始,表格是新的。
<操作><动作名词><动作名词秒><动作,演员><动作名词,演员><动作名词秒,演员>
所有提供的参数都传递给R_处理()
功能。这个演员
value(在逗号之后)将是第四个参数(如果提供)。因此,<动作,演员>
将调用R_Process(操作,0,0,参与者)
.
@
装配
从6.40开始,Glulx操作码@哈桑多
和@放弃撤消
支持(Glulx规范3.1.3)。
从6.42开始,Z代码操作码@设置真彩色
和@缓冲屏幕(_S)
支持(Z-Spec 1.1)。
从6.42开始,汇编语言(§41)允许您直接指定字节:
@->80亿美元04亿美元D2;
这会将给定的字节写入正在编译的函数的当前位置。字节值必须是数字或定义的数字常量。由作者负责确保字节构成有效的指令。
您还可以将值指定为单词:
@-->$00$FFEE;
在这种形式中,每个条目都被写为两字节(Z)或四字节(G)序列。这个@ -->
语句接受一般常量值,例如对象、字符串或函数地址。
打印
资本化(A)
打印令牌联接(a)
,(第页)
、和(第页)
截至6.30;参见§26。
印刷(A)灯;
这将调用CInDefArt()
单板功能。
如上所述(财产)
当$OMIT_SYMBOL_表格
选项。
交换机
从6.42开始,只要表达式是编译时常数,开关大小写值就可以是带括号的表达式。在以前的版本中,它们必须是文字或常量符号,前面可能有减号。
常数CONST=5;! 这些方法一直有效。开关(x){0:返回0;1:返回1;-2:返回-2;CONST:返回5;-CONST:返回-5;}! 截至6.42,这些功能也有效。开关(x){(0):返回0;(-(1)):返回-1;(CONST):返回5;(CONST+1):返回6;(CONST|3):返回7;}
如果案例不是以开放paren开头,则遵循旧规则:它必须是带可选减号的文字符号或常量符号。
一个案例也可能有多个值或多个表达式。只要第一值用paren包装。由于Inform解析逗号表达式的方式,将整个列表包装在parens中也是可行的。
开关(x){1,2,3:返回0!旧风格(4) ,(CONST),(CONST+1):返回1!新风格(10) ,CONST+6,CONST+7:返回2!这也行得通(20,CONST+16,CONST/17):返回3!这个也一样}
范围案例使用到
(例如3至7
)不能使用带括号的表达式。
不在转换
语句不能使用带括号的表达式。(这些情况通常出现在之前
和之后
属性等)如§4所述,这些顶级案例必须是裸动作名称。
动态字符串
DM4(§1.11)描述了“打印变量”,也称为动态字符串。通过嵌入以下代码@01
在字符串中,可以插入另一个文本字符串值。您可以使用如下语句设置插值
字符串1“text”;打印“这是@01.^”;
从6.40开始,动态字符串插值可能看起来像@(1)
,parens中包含任何非负数。你也可以写@(N)
,其中N个
是定义的数字常量。
常量TEXTVAL 1;
…然后。。。
字符串TEXTVAL“text”;打印“这是@(1),或等效@(TEXTVAL)。^”;
旧格式@01
仍然支持,但只支持正好两位数的数字。
动态字符串的数量是有限的,但随着$MAX_DYNAMIC_STRINGS(最大动态字符串)
设置。请参见编译器设置.
字典单词
从6.43开始,字典单词literal可能有一个后缀,指示要设置的标志目录par1
。后缀包含//
后跟任意数量的标志:
第页
:设置复数标志(位2)
秒
:设置单数标志(第4位)
n个
:设置名词标志(位7)
~p个
:这次不要设置复数标志
~秒
:这次不要设置单数标志
~n个
:这次不要设置名词标志
6.42支持相同的后缀,但秒
和~秒
第6.43节中增加了。
在6.41及更早版本中,只有//第页
后缀(§29)和无旗//
支持后缀(§1.4)。(无旗子形式“x//”
只是表示常量是dict单词。这有助于区分单字母dict单词和字符常量。)
Inform假设源代码中提到的所有单词都是名词。唯一的例外是动词
指令,包含动词和介词。实际上,属性、全局变量、数组或函数中提到的所有单词都默认为//n个
。应使用显式标记单词//~n个
如果你不想仅仅通过提及他们来给他们起名词性的作用。
相反,Inform从不假设单词是复数。因此,只有//对
和//~n个
标志很有用。//~p个
和//n个
仅为了一致性而支持。
注意,如果一个单词同时标记了//第页
和//~p个
在不同的地方,设置其复数标志。同样,如果标记了//n个
在任何地方,即使作为默认值,其名词标志已设置。这个~
表格不会擦除旗帜;他们只是阻止它被正确设置。
这个$DICT_IMPLICIT_SINGULAR=1
选项(添加在6.43中)告诉Inform假设非模糊名词是单数。也就是说,如果在源代码中提到一个单词(因此//n个
默认情况下),并且没有显式//第页
,然后是它//秒
标志已设置。如果一个单词同时标记了//第页
和//~p个
在不同的地方,它最终会二者都这个//秒
和//第页
旗帜。
这个$DICT_TRUNCATE_FLAG=1
选项(添加在6.43中)告诉Inform为超过的单词设置位6$DICT_WORD_SIZE($DICT_单词_大小)
因此会被截断。这包括以不完整的Z字符序列结尾的Z代码单词。没有//
这个位的后缀。和其他标志一样,如果一个单词在一个地方被截断,而不是在另一个地方(比如,如果两者都被截断“超级英雄”
和“超级英雄”
则设置标志。
常量
编译器定义了描述游戏文件的各种常量。游戏(和库)可以使用这些来检查编译的数据。
未定义给定值的常量通常用于检查#Ifdef公司
。它们的默认值为0。
#版本号
Z代码版本号。(仅限Z代码。)
#可读内存偏移
高内存(例程和字符串段)的起始地址。这也可以在地址4的标题中找到。(仅限Z代码。)
#字典表
字典的地址。在Z代码中,这也可以在地址8的标题中找到。(Glulx仅在6.40之前。)
#语法表
语法表的地址。在Z代码中,Inform将其放在静态存储器的开头,因此可以在地址14的标头中找到它。(Glulx仅在6.40之前。)
#操作表
操作表的地址。此表映射了一个操作编号(例如。##跳跃
)其操作程序(例如。跳转Sub
).
#目录par1,#dict_par2,#dict_par3
在Z代码中,字典词条中三个标志的字节偏移量。
在Glulx中,这些是低字节(第二个字节)。
如果$ZCODE_LESS_DICT_DATA
已设置,#dict_par3
不可用。
#标识符_表
包含属性名、属性名和其他代码元素的一组表的地址。这些通常仅由调试命令、运行时错误消息和中缀使用。
如果$OMIT_SYMBOL_表格
则此常数(和其他相关常数)不可用。尝试使用它们将被报告为编译错误。
目标_ Z代码,目标_ GLULX
根据游戏文件格式,将定义其中一个。
文字化
这是虚拟机字或地址的字节大小:Z代码为2,Glulx为4。
STRICT_模式,调试,INFIX(信息)
这些由-S公司
,-D类
,-X(X)
分别切换。
DICT_WORD_SIZE(DICT_世界大小)
这是字典单词字符串的字节大小(不是Z字符计数!)。在Z代码中,它将是4(v3)或6(v4+)。在Glulx中,它由$DICT_WORD_SIZE($DICT_WORD_SIZE)
设置。
DICT_ENTRY_字节
这是包括标志在内的完整字典条目的字节大小。在Z代码中,它将是DICT_WORD_SIZE+3
,或DICT_WORD_SIZE+2
如果$ZCODE_LESS_DICT_DATA
已设置。在Glulx中,它是DICT_WORD_SIZE+7
,或4*DICT_WORD_SIZE+12
如果$DICT_CHAR_SIZE($DICT_字符_大小)
为4。
DICT_CHAR_SIZE(图像_字符_大小)
字典单词中一个字符的字节大小。这由$DICT_CHAR_SIZE($DICT_字符_大小)
设置;它将是1或4。(仅Glulx。)
DICT_IS_代码
如果$DICT_CHAR_SIZE($DICT_字符_大小)
为4。(仅Glulx。)
OMIT_SYMBOL_表格
如果$OMIT_SYMBOL_表格
设置。
数字_文字_字节
每个对象记录中为(布尔)属性保留的字节数。(每个字节存储八个属性。)在Z代码中,这将是6。在Glulx中,它由$NUM_ATTR_BYTES($NUM_ATTR_BYTES)
设置;它始终是表单的值4*i+3
.
INDIV_PROP_启动
第一个单独属性的属性编号。这由$INDIV_PROP_START(美元)
设置。(仅Glulx。)(在Z代码中,此设置始终为64,因此未定义常数。)
GOBJFIELD_链条,GOBJFIELD_NAME(谷歌域名),GOBJFIELD_PROPTAB公司,GOBJFIELD_租金,GOBJFIELD_视图,GOBJFIELD_CHILD公司
Glulx对象记录中六个地址字段的字偏移量(不是字节!)。例如,对象属性表的地址可以在对象-->GOBJFIELD_PROPTAB
.(仅Glulx。)
GOBJ_EXT_启动
对象记录中扩展对象数据的字节偏移量。此数据的长度由$GLULX_OBJECT_EXT_BYTES(美元)
设置。(仅Glulx。)
GOBJ_总计_长度
完整对象记录的字节大小。这将是1+NUM_ATTR_BYTES+6*字号
,加上$GLULX_OBJECT_EXT_BYTES(美元)
如果设置好了。(仅Glulx。)
浮动_不确定性,浮动_无限,浮动_编号
Glulx浮点运算的正负无穷大和NaN。(仅Glulx。)
双HI_INFINITY,双重有限性,双HI_NINFINITY,双倍_LO_NINFINITY,双HI_NAN,DOUBLE_LO_NAN公司
Glulx双精度运算的正负无穷大和NaN。(仅Glulx。)
操作员
逻辑优先级
条件运算符表(§表1B)显示&&
,||
、和~~
具有同等优先权。对于以下表达式,这是不明确的(~~X&Y)
事实上,编译器一直(至少从6.0开始)将其解析为应用~~
连接(X和Y)
:
! 这些陈述是等价的:val=~~X&&Y;val=~~(X&&Y);
如果你想要~~
仅适用于X(X)
,必须添加显式括号:
! 不等同于上述!val=(~~X)&&Y;
类似地,按位表达式(~X&Y)
被解析为(~(X和Y))
.
鉴于此,考虑逻辑~~
运算符的优先级为1.5,按位~
运算符的优先级为5.5。
这个或
操作人员
这个或
§1.8中描述了操作员,但没有给出完整的解释。
或
只能用于在比较运算符右侧提供值列表:
如果(val==2或4或8)。。。如果(箱子或背包中的物品)。。。如果(obj有容器或支持者)。。。
如果左侧的值与右侧的任何值匹配,则表达式为true。
对于负意义运算符,如果左侧值匹配,则表达式为true没有人右边的值:
如果(val~=2或4或8)。。。如果(obj notin trunk or package)。。。如果(对象没有容器或支持者)。。。
当我们考虑排序比较时,这有点令人困惑。本手册给出了以下示例:
如果(x>100或y)。。。
[…]测试x是否大于最小值100和y。
这与前面的例子一致;如果(x>100)
或 (x>y)
然而,要意识到这一点,需要眯起眼睛。
这个>=
和<=
运营商更糟糕。编译器将这些视为消极感觉操作符(因为这是Z机器体系结构构造它们的方式)。因此:
如果(x<=100或y)。。。
这是真的,如果x个
小于或等于二者都 100
和 年
(也就是说,它被视为与前一示例完全相反。)即使你已经吸收了前一示例,这也是不直观的。
从6.36开始,如果您使用或
使用>=
和<=
运算符,编译器将生成警告。
班级行为
继承
DM4(§3.8)给出了多重继承的示例:
反对“下金蛋的鹅”类鸟类珍宝;
[This goose]首先从Object继承,然后是Bird,然后是Treasure,属性设置和属性值是从后面提到的类继承的,这些类覆盖了前面的类,所以如果这些类给出的指令相互矛盾,那么Treasury将得到最后的结果。
事实上,这不是真的(而且从来都不是)。语言行为有些复杂。
属性值由第一列出的类,是否作为指令提供(珍宝鹅
)或a班
关键字(对象鹅类宝物
). 当然,如果对象本身提供了属性值,则会覆盖所有继承的值。
如果一个类继承了另一个类,那么派生类属性会像人们所期望的那样覆盖超类属性。
添加剂属性遵循相同的逻辑,但它们的值会累积,而不是相互覆盖。加法属性从对象自己的定义中获取值(首先),然后从每个类中以(正向)列表顺序获取值。
属性遵循相同的规则,除了类不能对其他类设置的属性求反.
类鸟有~重;班宝有重;物鹅类鸟宝;
在本例中,鹅对象获得重的
属性,因为它至少有一个类设置了它。无论这些类的排列顺序如何,这都是正确的有~重
类中的声明鸟
没有效果。
对象当然可以使用具有~attr
否定从类继承的属性。派生类可以否定从超类继承的属性。该限制仅适用于对象类之间的冲突。
等级复制
和重新创建
这个复制
和重新创建
类方法也与手册不同。§3.11规定:
Plant.copy(Gilded_Branch,Poison_Ivy);Treasure.recreate(Gilded_Branch);
它非常有用,可以为任何实例发送重新创建和复制,而不仅仅是以前创建的实例。例如,[上面的copy语句]将植物的所有特征从Poison_Ivy复制到Gilded_Branch,但只保留镀金树枝的任何其他属性和属性。同样,[重新创建声明]只重置与Treasure有关的属性,而不重置工厂属性。
事实上,什么类产生了属性和属性的问题并没有出现。这个复制
方法副本全部的从源头到目标的积极和消极属性。它还复制源和目标声明的每个属性的值,每个属性的长度都相同。
这个重新创建
方法执行复制
来自未修改的类实例,后跟创造
呼叫。因此,它将重置所有属性,以及对象和类声明的任何属性。
Glulx支架
编译Glulx游戏文件(-G公司
选项)于6.30引入。这是对Inform语言的一些补充。
常量之一目标_ Z代码
和目标_ GLULX
始终是定义的。这些可以与Ifdef公司
用于标记只应在一个平台上编译的代码的指令。
常量文字化
始终定义;Z代码中为2,Glulx中为4。
如上所述Ifv5型
该指令也是为Glulx编译的。
只有Glulx支持的语言功能
如果函数的第一个参数命名为_变量计数
,参数将在VM堆栈上传递_变量计数
设置为参数数。
以开头的文字$+
和$-
编译为浮点常量。例如:$+1.0
,美元-1e3
,$+2.5e-3美元
.也支持双精度浮点;这些值需要64位,或者每个需要两个Glulx字,因此被写入$>+1.0
(高位词)和$<+1.0
(低字)。
常量浮动_不确定性
,浮动_无限
,浮动_编号
,双HI_INFINITY
,双重有限性
,双HI_NINFINITY
,双倍_LO_NINFINITY
,双HI_NAN
,DOUBLE_LO_NAN公司
也定义了。
这个打印_数组()
方法(§3.12)需要两个参数,而不是一个参数(如Z代码)。
Glulx中不支持的语言功能
中缀(-X(X)
选项§7)不可用。
这个Z字符
指令(§36)不可用,因为Glulx不使用ZSCII字符集。
这个节约
,恢复
、和阅读
声明(§1.15、§2.5)不可用。这些功能需要Glulx中更复杂的行为,不能封装在单个语句中。它们必须使用@glk公司
操作码。
Z机器V3/4限制
Inform的早期版本(通过Inform 5)旨在支持从3到6的所有Z-machine版本。然而,Inform 6以需要更高级VM支持的方式扩展了该语言。因此,某些语言功能需要Z-machine版本5或更高版本。
- 调试模式和严格模式(
-天
和-S公司
,§7)在V3和V4中不可用。
- 方法调用表达式
对象prop()
在V3和V4中不可用。
你可以解决缺乏对象prop()
通过书写:
@推动自我;自我=对象;地址=obj.prop;addr();@自我牵引;
一般来说,如果源代码和图书馆避免了对象prop()
语法。这意味着您不能使用Inform 6库。您必须使用通知5图书馆,或为V3设计的替代库之一,例如地铁84或惩罚通知.
原始语法表格式记录在通知技术手册(§8.6),但它们已扩展到Glulx,然后扩展到语法版本3(从6.43开始为新版本)。在这里编写摘要很方便。
语法表是-->
从地址开始的数组#语法表
在Z代码中,数组是基于0的,是静态内存中的第一件事。在Glulx中,数组是基于1的;第一项是动词的数量。数组包含每个动词的各个语法表的地址。
单个语法表如下所示:
[Z代码GV1]byte:行数…每个语法行:{字节:参数计数…行中的每个标记:{字节:令牌}byte:动作编号}[Z代码GV2]byte:行数…每个语法行:{短:操作+标志…行中的每个标记:{byte:标记类型short:令牌数据}字节:结束(15)}[Z代码GV3]byte:行数…每个语法行:{短:计数+操作+标志…行中的每个标记:{byte:标记类型字节:令牌数据}}[Glulx(始终为GV2)]byte:行数…每个语法行:{short:操作编号字节:标志…行中的每个标记:{byte:标记类型long:令牌数据}字节:结束(15)}
笔记:
- 在Z代码GV1中,每行正好有6个标记(因此语法行是8个字节)。未使用的标记为零。这个
参数计数
是的数字不重新定位行中的标记。
- 在Z代码GV2中
操作+标志
单词是用底部10位中的操作数编码的。第10位是颠倒
标志。前5位未使用。
- 在Z代码GV3中
计数+操作+标志
单词是用底部10位中的动作编号进行编码的。第10位是颠倒
标志。前5位是令牌计数。(因此不需要ENDIT。)
- 在Glulx中,标志和操作号是单独的字段。这个
颠倒
标志为的位0旗帜
.
有关完整的令牌格式,请参阅ITM公司但请注意,在GV2(Z/G)中,范围例程标记包含例程地址,介词标记包含dict地址;因此,令牌数据是字大小的。在GV1/3中,这些令牌数据值是字节;地址必须分别在(命名错误的)“预作用”和“形容词”表中查找。
这个-k个
switch生成游戏信息.dbg
描述已编译游戏的文件。这个通知技术手册(§12.5)记录了该文件的二进制格式(“版本0”)。但是,不再使用该格式。从Inform 6.33开始,生成了更详细的XML格式(“Version 1”);本节对其进行了描述。
概述
调试信息文件用XML编写,并用UTF-8编码。因此,他们以以下声明开头:
<?xml version=“1.0”encoding=“UTF-8”?>
除了对格式良好的XML的通常要求之外,该文件还遵循以下约定:所有数字都以十进制书写,所有字符串都区分大小写,二进制文件的所有摘录都是以Base64为编码的。
顶级
根元素由标记给出<告知故事文件>
有三个属性:使用的调试文件格式的版本、生成该文件的程序的名称以及该程序的版本。例如,
<inform-story-file version=“1.0”content-creator=“通知”content-creator-version=“6.33”>...</inform-story-file>
以下描述的任何元素(除了<局部变量>
,<序列点>
,<源代码位置>
)可能出现在省略号中。
故事文件前缀
故事文件前缀包含故事文件第一个字节的Base64编码,因此调试工具可以轻松检查故事和调试信息文件是否不匹配。例如,Glulx故事的前缀可能显示为
<故事文件前缀>R2x1bAADAQEACqEAAAwsAAAMLAAAAQAAAAAAAPAAIo2Jc6B2XSW5mbwABAAA2LjMyMC4zOAABMTIxMDE1wQAAMA公司==</story-file-prefix>
故事文件前缀是必需的,但未指定其长度。Inform编译器的当前版本记录64个字节,这似乎已经足够了。
故事文件部分
故事文件部分根据数据的使用方式对故事文件进行分区。对于Inform 6编译器,此分区与-z(z)
开关。
故事文件节的记录给出了该节的名称、开始地址(包括开始地址)和结束地址(不包括结束地址):
<故事情节>缩写表<地址>64<结束地址>128</story-file-section>
目前使用的名称包括《Inform Technical Manual》中的名称(§12.5):
缩写表收割台扩展(仅限Z代码)字母表(仅限Z代码)Unicode表格(仅限Z代码)属性默认值对象树通用属性类别编号单个特性(仅Z代码)全局变量阵列空间语法表操作表解析例程(仅限Z代码)形容词表(仅限Z代码)词典代码区字符串区域
再加上一个Z代码:
缩写
Glulx的两个附加项:
内存布局id字符串解码表
两个目标都增加了三个:
收割台标识符名称零填充
姓名可以重复;例如,Glulx故事文件有时有两个零填充部分。
不希望细分故事文件的编译器应该为整个故事文件发出一个部分,并为其命名
故事
源文件
源文件的编码如下例所示。每个文件都有一个唯一的索引,其他元素在引用源代码位置时使用该索引;这些指数从零开始计算。文件的路径以两种形式记录,首先是通过命令行参数或include指令提供给编译器的,但没有任何路径缩写,如>
(适合呈现给人类的表单),然后解析为绝对路径(适合加载文件内容的表单)。所有路径都是根据主机操作系统的约定写入的。目前,语言是“通知6”或“通知7”。未来可能会添加更多语言。
<源索引=“0”><given-path>示例.inf<resolved-path>/home/user/directory/example.inf<language>通知6</source>
如果已知源文件出现在故事的Blorb中,则还将记录其区块号:
<源索引=“0”><given-path>示例.inf<resolved-path>/home/user/directory/example.inf<language>通知6<blorb-chunk-number>18</来源>
表格条目;语法行
表条目是由源代码的特定部分定义的数据,但没有任何相应的标识符。这个<表格输入>
元素记录条目的类型、开始地址(包含)、结束地址(不包含)以及定义的源代码位置(如果有):
<表格输入><type>语法行</type><address>1004</address><结束地址>1030<源代码位置></源代码位置></table-entry>
Inform编译器的当前版本仅发出<表格输入>
语法行标记;这些数据都位于语法表部分。
命名的值
命名值的记录存储其标识符、值和定义的源代码位置(如果有)。例如,
<常数>MAX_SCORE<值>40</value><源代码位置></源代码位置></常数>
将表示命名常量。
属性、属性、动作、假动作、对象、数组和例程也是数字的名称,仅在用法上有所不同;它们在标记下以相同的格式表示<属性>
,<属性>
,<操作>
,<假动作>
,<对象>
,<数组>
、和<例行程序>
。(此外,与版本0不同,假动作不会同时记录为假动作和动作。)
常数记录包括《信息技术手册》(§12.2)中列出的系统常数的一些额外条目,即使这些不是由常数指令创建的。的条目#不设防的
ed常量也包括在内,但必须没有值。
对象的一些记录将表示类对象。在这种情况下,他们将获得标签<类别>
而不是<对象>
并包括一个额外的孩子,以表明他们的班级编号:
<类别>灯<类编号>5<值>1560</value><源代码位置></源代码位置></类>
数组的记录还有额外的子项,这些子项记录了数组的大小、元素大小以及第0个元素的预期语义:
<数组><identifier>路由</identifier><值>1500</value><字节计数>20</字节计数><字节-每个元素>4<zeroth-element-holds-length>真<源代码位置></源代码位置></array>
最后,<例行程序>
记录包含<地址>
和a<字节计数>
元素,以及任意数量的<本地变量>
和<序列点>
元素,描述如下在下面。提供地址是因为标识符的值可能被打包。
有时,命名值实际上是匿名的;未命名对象、嵌入例程、某些替换例程、贴面属性和中缀属性都是示例。在这种情况下<标识符>
子元素将携带XML属性
人造的
以表明编译器正在提供自己的合理名称,该名称可以呈现给人类,但实际上不是标识符。例如:
<例行程序><identifier artificial=“true”>提灯.time_left<值>1820</value><字节计数>80</字节计数><源代码位置></源代码位置>...</例行程序>
人工标识符可以包含字符,如灯.时间_左侧
,这在源语言中是不合法的。
全局变量
全局参数与命名值相似,只是它们不被解释为固定值,而是有一个可以找到其值的地址。因此,他们的记录包含<地址>
标记代替<值>
标签,如:
<全局变量><identifier>黑暗目击</identifier><地址>1520<源代码位置></源代码位置></global-variable(全球变量)>
局部变量
局部变量的格式与全局变量的格式类似,只是从来没有包含源代码位置,并且它们的内存位置不是由地址给定的。对于Z代码,局部变量由索引指定:
<本地变量><identifier>参数<索引>1</index></local-variable>
而对于Glulx,它们由帧偏移指定:
<本地变量><identifier>参数<帧集>4</local-variable>
如果局部变量标识符仅位于例程的一部分的作用域中,则其作用域将被编码为起始指令地址(包含)和结束指令地址(不包含):
<本地变量><identifier>规则手册</identifier><索引>0</index><范围地址>1628<end-scope-address>1678</local-variable>
具有不连续作用域的标识符记录为一个<本地变量>
每个相邻区域的元素。只要相应的范围是不相交的,同一个标识符就可以映射到不同的变量。
序列点
序列点存储为指令地址和源代码中相应的单个位置:
<序列点><地址>1628</地址><源代码位置></源代码位置></序列点>
源代码位置始终正好是一个端点重叠的位置。
序列点的定义与《Inform Technical Manual》(§12.4)中相同,但进一步规定标签不会影响其源代码位置,就像在版本0中一样。例如,在代码中
说_p=1;ParaContent()。L_Say59。LSayX59;t0=0;
序列点的位置如下:
说p=1ParaContent()。L_Say59。LSayX59;t0=0;
而不是像这样:
说p=1ParaContent();<*>。L_Say59。LSayX59;t0=0;
源代码位置
大多数源代码位置采用以下格式,其中描述了它们的文件、它们开始的行号和字符号(包含在内)、它们结束的行号与字符号(不包含在内)以及与这些端点对应的文件位置(以字节为单位):
<源代码位置><file-index>0</file-index><line>1024</line><字符>4</字符><文件位置>44153</文件位置><终点线>1025</终点线><结束字符>1<最终文件位置>44186</source-code-location>
行号和字符号从一开始,但文件位置从零开始计数。
在端点重合的特殊情况下,就像序列点一样,可以省略端点元素:
<源代码位置><文件索引>0</文件索引><line>1024</line><字符>4</字符><文件位置>44153</文件位置></source-code-location>
另一方面,有时定义跨越多个源文件或以两种不同的语言出现。前一种情况是通过包含多个代码位置元素并对其进行索引以指示顺序来处理的:
<!-- Inform 6定义的第一部分--><源代码-位置索引=“0”><!-- 假设文件0的语言为“Inform 6”--><file-index>0</file-index><line>1024</line><字符>4</字符><文件位置>44153</文件位置><终点线>1025</终点线><结束字符>1<最终文件位置>44186</source-code-location><!-- Inform 6定义的第二部分--><源代码-位置索引=“1”><!-- 假设文件1的语言为“Inform 6”--><file-index>1</file-index><line>1</line><字符>0</字符><文件位置>0</文件位置><终点线>3</终点线><结束字符>1</结束字符><end-file-position>59</end-file-pposition></source-code-location>
后一种情况也使用多个元素进行处理。请注意,索引仅用于指示同一语言中位置之间的顺序。
<!-- 通知7定义--><源代码位置><!-- 假设文件2的语言为“Inform 7”--><file-index>2</file-index><行>12</line><字符>0</字符><文件位置>308<终点线>12</终点线><end character>112</end character><最终文件位置>420</source-code-location><!-- 通知6定义--><源代码位置><!-- 假设文件0的语言为“Inform 6”--><file-index>0</file-index><line>1024</line><字符>4</字符><文件位置>44153</文件位置><终点线>1025</终点线><结束字符>1<最终文件位置>44186</source-code-location>
漏洞
自Inform 6.21以来,已修复了大量错误。此处不包括该列表。请参阅发行说明有关详细信息(旧注释在这里).
然而,值得注意的是,自6.15以来,Z代码V3代码的生成被忽略了,并且出现了一些错误。6.34和6.35解决了这些问题;V3应该再次可用。
特别感谢丹尼尔·弗里蒙特(Daniel Fremont)在他的输入模糊化项目中发现了许多错误报告。