Source Insight宏语言语法

来源:互联网 发布:域名301重定向会跳转吗 编辑:程序博客网 时间:2024/06/01 08:28
本章讲解Source Insight的宏语言,SourceInsight 的宏语言语法与C语言比较接近,本章节要求已经熟悉基本的编程思想。
This chapter describes the Source Insight macro language. The Source Insight macro language syntax is similar to C. This chapter assumes you are familiar with basic programming concepts
原文:http://www.sourceinsight.com/docs35/Macro%20Language.htm

一. 概述

sourceinsight 提供了一种类似C语言的宏语言,这种语言对脚本命令、插入特定文字和自动化编辑非常有用。
宏语句义txt格式保存,后缀名为.em, 这个文件可以直接添加到当前工程中、任何在Project Symbol 路径下的工程或 base project中,一旦宏文件变成project的一个部分,文件中宏函数就可以在Key Assignments和Menu Assignments 对话框中使用。

1 基本语法规则

Source insight 的宏语言不是大小写敏感的,会自动忽略空格,不要求“;”,如果有“;”的会被忽略掉。另外变量名必须以字母开头,而不能以数字开头。

1.1 函数

函数的定义比较类似C语言,忽略空格,函数名和变量对大小写不敏感
函数的定义格式:
macro my_macro()
{
/* 注释*/
.. statements.. // 注释
}
可以向函数传递参数和调用其他函数。也可以返回一个值,像这样 " return n",这里n就是返回值。
macro add2(n)
{
return n + 2
}

1.2作用域和引用

所有的宏存在于一个全局的作用域中,所有定义在任何打开的文件、保存在工程、或在一个项目符号路径下的工程中的宏都在作用域内。也就是说可以对宏前向引用,不需要再调用前声明。
当执行宏或用户提出宏请求时,SI 使用自身的符号查找引擎通过名字决定引用。符号查找的内容请参考“项目”章的“符号和项目”节。
当编辑宏时,也可以使用变量查找技术来定位宏函数。(参考“Projects”章的“Finding Symbols in your Project”)如,你可以在项目符号浏览器中输入宏名字,并且跳转到它的定义位置。

1.3 运行宏

可以直接用按键或menu菜单运行一个宏,也可以用Run Macro命令在当前鼠标位置开始执行一个宏语句。

1.4 宏作为命令

SI 把无参数的宏作为用户级命令,宏命令出现在Key Assignments 命令列表和 Menu Assignments对话框中。这样就允许你把宏命令放在菜单项中和键盘映射中。也可以直接从这些对话框中运行命令。如果宏函数带有参数,就不会出现在命令列表中,也不可以用作键盘命令和menu命令。
注意: 编辑用户级宏函数的方法是选中一个命令时按下Ctrl键。命令的宏函数定义就会显示出来。
如果在宏文件中创建了一个新的命令,必须先保存那个宏文件,在添加到菜单或键盘映射前先同步到项目数据文件中。
也可以把宏保存到Base Project中,或其他在项目符号路径下的工程中。在应用宏名字时,SI会到这些工程中搜索它。
注意:如果不以.em后缀保存宏文件,SI不会把宏函数作为用户级命令。

1.5 运行内联宏语句

Run Macro命令从鼠标的当前位置开始执行一个宏段落。这允许你在任何类型的文件中执行代码可见的宏段落。在调试宏代码时这会非常实用。当运行位于程序注释中的内嵌的宏段落时内联宏段落也非常有用。要记住在段的最后使用stop声明,否则宏解释器会尝试执行超出范围的语句。
如下面的内联宏位于一个C语言的注释中,查找对ucmMax 标志的引用,并重编所有引用它的文件。使用时,把鼠标放在第一行然后运行Run Macro命令。
#define ucmMax 120
/* Macro: touch all ucmMax references:
// to run, place cursor on next line and invoke “Run
Macro”
hbuf = NewBuf("TouchRefs") // create output buffer
if (hbuf == 0)
stop
SearchForRefs(hbuf, "ucmMax", TRUE)
SetCurrentBuf(hbuf) // put search results in a window
SetBufDirty(hbuf, FALSE); // don’t bother asking to save
Stop
*/

1.6 语句

宏由独立语句组成。2个或更多语句的组合用花括号{}围起来。
1个语句可以是下列之一:
一个宏语言元素,如if while语句。这些元素下面会介绍
一个指向用户定义的宏函数。你可以定义和保存宏函数在一个宏文件中。
一个指向内部红函数的调用,如 GetCurrentBuf。SI有许多内建的函数。将在以后的章节描述。
一个宏命令请求,像Line_UP 或 Copy。所有的用户级命令在SI宏语言中都是可用的。调用一个用户命令,仅使用命令名称,不要使用参数。也不用使用括号。如果命令名称包含空格,则要用下划线 “_”代替空格。如调用“Select All”命令,应该写Select_All
函数和变量不分辨大小写。
语法与C语言和Java的语法比较像,不需要额外的分号,分号会被忽略。如果想保持写作习惯带上分号也不影响。
下面是一些实例语句:
hbuf = OpenBuf(“file.c”) // call internal function
SaveBufAs(hbuf, “filenew.c”) // call internal function
Select_All // call user-level command “Select All”
Copy // call user-level command “Copy”
Line_Up // call user-level command “Line Up”
x = add2(n) // call user-defined macro function add2.
想停止执行,使用stop
如果从Source Insight 中运行一个包含对话框宏的命令,对话框就会显示
下表列出了基本的宏语言元素。

Table 6.1: Macro Statements

Statement

Description

break

Exits a while loop.

if (cond)… else

Tests a condition.

continue

Continues a while loop at the top.

return n

Returns n from a function.

stop

Stops executing the macro.

while (cond)

Loops while cond is true.

来源: <Statements>

二 变量

定义一个变量只直接指定一个值就行,不需要声明。然而,你可以使用var语句显式声明一个变量。
变量名不分辨大小写,必须以字母开头,不能用数字。
所有的变量都是字符串变量。没有像c语言里的变量类型,也不需要声明。这样使用变量就非常简单,不需要类型转换盒计算。而且不需要对字符串进行内存管理。

1. 声明变量

使用var 语句声明一个简单的本地变量。
var variable_name
变量是可以不用声明的,但这样做是有好处的
* 调用时有助于语法分析
*变量被初始化为一个空的字符串,所以在使用时不会因为没有初值而困惑
如下面的函数:
macro SomeFunction()
{
var localx
// "localx" is displayed with "Ref to Local" style
localx = 0
}

2.变量初始化

直接为变量赋值就可以初始化。如果想为变量初始化一个空值,使用常数 nil
如:
S = nil // s is set to the empty string
S = "" // same thing

3. 变量展开

如果一个标示是一个变量名,则会被展开为它的字符串值,否则被直接作为一个字符串。另一种情况是被双引号包含的标示被直接看做字符串。

For example:

s = abc // same as s = "abc" if abc is not defined

..or..

abc = Hello
s = abc // same as s = "Hello" (if Hello is not
defined!)
s = "abc" // s equals "abc"
为了避免变量被直接用作字符串,养成用var 声明的习惯

4.在字符串中展开变量

使用@字符将一个变量插入到另一个字符串。当一个被@字符包括的变量名出现在字符串中时,sourceinsight直接将@varible@用变量值替换。
如:
S = “Hey, @username@, don’t break the build again!”
这个例子中用变量值替换@usename@
要逃逸@字符,使用\或两个@。如
S = “Mail info@@company.com for information.”

5.变量运算

尽管变量以字符串方式存在,数学运算也是可以的
s = "1"
x = s + 2 // x now contains the string "3"
y = 2 * x + 5 // x now contains "11"
数字变量使用起来非常自然,根本不用关心他们是怎样保存的。唯一需要注意的是如果变量包含有无法评估为数字的字符串时,就会报错
s = "hello"
x = s + 1 // error
想知道变量是不是字符串使用 IsNumber函数
if (IsNumber(x))
x = x / 4 // okay to do arithmetic
变量不支持浮点运算。

6. 索引变量

可以像字符串数组一样索引变量。索引号从0开始。如:
s = "abc"
x = s[0] // x now contains the string "a"
索引变量会产生一个只包含一个字符的字符串
索引变量最后一个字符的下一位会返回空字符串。与c语言以0结束字符串比较相似,只有0字符是空字符串。

7.Record 类型

虽然不支持C语言类型的结构体,支持另一种聚合样式 record 变量。一个record 实际上是分开的“name=value”数值对列表。使用方式上和c语言的结构体是一样的。
内部函数经常返回record变量,因为这是一种方便的方法。
record域用过逗号来引用,格式为<recordvar>.<fieldname>
如,从一个符号查找记录中读取符号所在文件位置
Filename = slr.file // get file field of slr
LineNumber = slr.lnFirst // get lnFirst field of slr
为一个变量赋值使用同样的方法
userinfo.name = myname; // set “name” field of userinfo
使用nil初始化一个空记录
userinfo = nil // make a new empty record
userinfo.name = “Jeff” // begin adding fields

8 .Record 变量的存储

record变量存储和字符串一样。每个域以“fieldname=value”对的方式保存,以分号分割
name=”Joe Smith”;age=”34”;experience=”guru”
如果想为record 整体赋值,必须用双引号包括要赋的,并且用反斜杠转义每一个引号。如
rec = “name=\”Joe
Smith\”;age=\”34\”;experience=\”guru\””
每次为一个域赋值却很简单
Rec = nil // initializes as an empty string
Rec.name = “Joe Smith”
Rec.age = “34”
Rec.experience = “guru”
record的域没有固定的顺序。record 变量没有通过特定的结构进行声明,所以你可以在任何时候创建一个域,只需要简单的指定一个值

For example:

Location = GetSymbolLocation(symname)
Location.myOwnField = xyz // append a field when you feel
like it!

9.数组技巧

SI不支持数组变量,但是可以使用文件buffer作为动态数组。buffer中的每一行可以座位数组的一个元素。另外, record的变量可以保存成一行,形成record数组
buffer的函数会在下面章节介绍。比较有用的函数式NewBuf和CloseBuf 用来创建和删除buffers。管理buffer 行的函数,GetBufLine,PutBufLine,InsBufLine,ApendBufLine,DelBufLine, GetBufLineCount。也可以调用NewWnd 来把buffer放入一个窗口,这样就可以看到数组内容。
创建一个record buffer组
hbuf = NewBuf()
rec = “name=\”Joe
Smith\”;age=\”34\”;experience=\”guru\””
AppendBufLine(hbuf, rec)
rec = “name=\”Mary
X"\”;age=\”31\”;experience=\”intern\””
AppendBufLine(hbuf, rec)
// hbuf now has 2 records in it
rec = GetBufLine(hbuf, 0) // retrieve 0th element
CloseBuf(hbuf)
三 . 特殊常量
有一些常量在宏运行之前就已经被定义。和其他的表示一样,这些常量也是不区分大小写的。
四 操作
大部分二元操作符和C语言是一样的。操作优先级也是和C语言一样。

Table 6.3: Operators

Operator

Meaning

+ and -

add and subtract

* and /

multiply and divide

!

Invert or “Not”. E.g. !True equals False.

++i and i++

pre and post increment

--i and i--

pre and post decrement

||

logical OR operation

&&

logical AND operation

!=

logical NOT EQUAL operation

==

logical EQUAL operation

<

less than

>

greater than

<=

less than or equal to

>=

greater than or equal to

#

string concatenation

"@var@"

variable expansion. used inside of quoted strings to expand a variable in the string.

然而 变量可能包含有非数字值,相关操作如下:

Table 6.4: Relational Operators for Strings

Operator

Meaning

==

strings must be equal (case sensitive)

!=

strings must not be equal (case sensitive)

<
>
<=
>=

strings are converted to numbers and then compared. Empty strings or strings that are non-numeric result in a runtime error.