前言
想開發一些小工具,所以想系統性的學習一遍aardio,之前都是哪裡不會搜哪裡,順便寫些教程。我的主要語言是Python,所以會以Python作為對比來加深印象。
aardio的基礎語法和JavaScript基本類似,如果你學過JavaScript,aardio很容易上手。下面的文件來自官方文件 [1]
問題搜尋途徑
基礎語法看:https://bbs.aardio.com/doc/reference/
一些庫的使用,獲取文件有以下途徑:
- aardio官方論壇(https://bbs.aardio.com),我一般用谷歌搜尋 site:bbs.aardio.com 搜尋內容
- aardio官方公眾號
- 開啟編輯器開始頁的話有開發指南和文件資源,右側有官方資訊,剛入門都可以看一下。裡面的庫函式文件我經常用
- 寫一個函式的時候右鍵轉到定義,庫程式碼下面一般都有註釋怎麼用
- 用vscode開啟整個aardio軟體目錄,搜尋你不知道怎麼用的庫,看看官方是怎麼使用的,這個我用的最多
- aardio相關的第三方論壇:https://aardio.online/thread-20.htm
語法
識別符號
變數識別符號的定義和Python基本一樣,語法如下:
- 字母(區分大小寫)、數字和下劃線,也可以用中文
- 數字不能作為變數首個字元
與Python不同的點:
- 除了單個下劃線
_
,其他下劃線開頭的為常量,定義後無法被修改 - 可以以$符開頭
- 包含中文時,前面不能有字元和數字
關鍵字
- | - |
---|---|
var 用於定義區域性變數 |
def 用於定義關鍵字 |
and not or 邏輯運算子 |
begin end 用於包含語句塊 |
if else elseif 用於條件判斷語句 |
for in 用於迴圈語句 |
select case 用於條件判斷語句 |
try catch 用於捕獲異常 |
break continue 迴圈中斷語句 |
function 用於建立函式 |
namespace 用於建立或開啟名字空間 |
import 用於引用庫 |
this 用於在類內部表示當前例項物件 |
global 用於表示全域性名字空間 |
owner 用於表示呼叫函式的主體物件 |
while do 用於迴圈語句 |
null 用於表示空值 |
false true 用於表示布林值 |
class ctor 用於建立類 |
return 用於函式中返回值 |
with 用於開啟名字空間 |
self 用於表示當前名字空間 |
你如果閒的無聊的話,也可以使用def
自定義關鍵詞,比如:
def 如果 = if
def 否則 = else
def 否則是 = elseif
def 名字空間= namespace
def 迴圈 = while
io.open();
如果 1== 1 {
io.print(" 1等於1 ")
}
否則{
io.print(" 1不等於1 ")
}
改個名字和圖示,一款新的中文程式語言就寫好了
分隔符和註釋符
分隔每條語句可以用換行或者分號, 一下三種方法都可以:
var a = 1; var b = 2;
var a, b = 1, 2;
# 後面的分號可寫可不寫,我一般都寫上
var a = 1
var b = 2
註釋則是使用//
和/*
加*/
,也可以使用多個/***
和***/
,只需要前面和後面的數量對應上
運算子
算術運算子 | + 加 |
- 減 |
* 乘 |
/ 除 |
** 冪 |
% 模 |
按位運算子 | ~ 取反 |
& 與 |
` | ` 或 | ^ 異或 |
<< 左移 |
等式運算子 | == |
!= |
||||
邏輯運算子 | ! not |
` | or :` |
&& and ? |
||
關係運算子 | > |
< |
>= |
<= |
||
連線運算子 | ++ |
|||||
取長運算子 | # |
|||||
全域性變數定義 | :: |
|||||
成員運算子 | . |
[] |
[[]] |
|||
包含運算子 | $ |
|||||
- 字串之間使用關係運算子時,是從第一個字元開始比較,這個和Python也是一樣的
++
並不是c語言裡面的自增,而是用於字串和字串拼接,或者字串和數值拼接。例如:1 ++ "2" == "12"
,也可以省略成1+"2"
- 取長運算子用於獲取字串和陣列長度,如果是物件則呼叫
_len
元方法 - 在變數名前面加
::
表示為全域性常量,比如::Kernel32 := raw.loadDll("Kernel32.dll");
,可以避免重複載入dll - 成員運算子.和[]基本可以混用,除非成員名稱不符合aardio命令規定則使用[]
- [[]]一般是在元方法中使用,它不會呼叫元方法,可以避免無限遞迴
- 路徑字串前加
$
符表示內嵌該檔案到編譯後的exe中
邏輯運算子
||
、or
和:
再使用上基本沒有區別,大部分情況下可以互相替換。
- 邏輯與和邏輯或運算子就能組成類似三元運算子的效果
true ? 1 : 0
a := 1
等同於a = a : 1
,可以用於避免重複賦值a ?= f(a)
等同於a = a ? f(a)
,可以只當a不為null執行f(a)- 也有像Python一樣的用邏輯運算子做條件取值的操作,比如
a = 1 or 2
、b = 0 or 3
。語法和意思也和Python是一樣的
按位無符號右移
a >>> n
將數值a按位向右移動n位(如果n大於等於32,則為n對32取模結果的位數) ,不保留符號位(負數不保持最高位為1,因此右移後會變成正數)
實際用途:
可以透過右移 0 位將有符號數強制轉換為無符號數。例如 -1 >>> 0 的值為 0xFFFFFFFF , 其作用等價於 raw.convert( {int value = -1},{INT value}).value。
不宣告呼叫靜態 API 預設會返回 32位有符號整數,如果原 API 返回的是 32位無符號整數,那麼只要簡單的將返回值 >>> 0 就可以得到原來的無符號數值了
這裡有一點很重要: 記憶體裡的資料都是0和1,它是什麼值只取決於你以什麼型別讀取它。
等式運算子
基礎資料型別會判斷值是否相等,而非基本型別則是判斷物件是否相等或者呼叫_eq
元方法判斷
元方法類似Python的魔法方法,可以過載物件的符號運算,比如_eq
過載==
。
0, null
與 false
相等,其他型別都與true
想等
跟數值型別比較時:
- 字串會自動轉為數值型別再做比較,空字串""轉為0,空白字元
\r\n\t
也是轉為0 - 如果是物件,則是呼叫
_tonumber
元方法轉數值
表示式 | 結果 |
---|---|
"123"==123 |
true |
"abc"==123 |
false |
""==0 |
true |
'\r\n\t '==0 |
true |
null==0 | false |
還有一個恆等判斷的符號===
和!==
,它不會呼叫_eq
元方法,直接判斷型別和數值都相等
運算子優先順序
這個東西沒必要記,有疑問時加括號即可。遇到別人的程式碼有疑問,可以執行測試下
基礎資料型別
型別 | 舉例值 | 說明 |
---|---|---|
type.null |
null | |
type.boolean |
布林值 | |
type.number |
數值 | 預設為64位浮點數 |
type.string |
字串 | 字串和Python也基本一樣,utf-8編碼 |
type.buffer |
raw.buffer | 可用於接收c語言char* 資料 |
type.pointer |
指標 | 接收dll返回的指標資料,或者使用topointer(obj) |
type.table |
表 | aardio中的陣列、字典等複雜型別 |
type.function |
函式 | function建立的函式 |
type.cdata |
核心物件 | 一般不用關心 |
type.fiber |
纖程 | 沒用過 |
type.class |
類 | class關鍵詞建立的類 |
null
任何沒有定義或賦值的變數預設都是null。如果函式不傳引數,預設傳過去的也是null。
import console;
console.dump(a);
console.pause(true);
import console;
function f(a){
console.dump(a);
}
f()
console.pause(true);
數值型別
2#11
表示二進位制數,8#11
表示八進位制數,16#A
表示十六進位制數,也可以表示為0xA
。2e+20
(2x10**20)表示科學計數法,+
僅表示指數的正負,可加可不加- 可以用
_
來分隔數值,111_222
等同於111222
字串
aardio中定義的字串都是utf-8編碼
string.fromUnicode(s)
、string.toUnicode(s)
可以做utf-8 <=> utf-16
的轉換,Windows上使用的Unicode編碼一般就是指的utf-16,兩個函式都可以指定第二個引數,代表目標編碼的內碼表,用於轉換其他編碼。
常用的內碼表: 936(gb2312)、1200(utf-16 le)、1201(utf-16 be)、65001(utf-8)。所有內碼表可以參考: 標準內碼表(codepage)列表 [2]
Windows可以在cmd下使用chcp
命令檢視當前使用的內碼表,一般情況下都是936。
定義字串的話有四種方式: 雙引號("")、單引號('')、反引號(``)和註釋符(/**/)。其中雙引號和反引號用法是一樣的
都可以定義多行字串:
a = "1
2";
b = '1
2';
c = /*1
2*/
不同點:
- 只有單引號可以使用跳脫字元,例如
'\n'
表示換行。 - 單引號的換行會被忽略,所以單引號表示換行時和c語言一樣使用跳脫字元
\n
- 雙引號的換行會被替換成
\n
- 註釋符的換行會被替換成
\r\n
- 在雙引號中可以使用兩個雙引號表示雙引號本身,例如
"1222""11111"
,則等同於'1222"11111'
- 在單引號中
\'
表示單引號本身, 例如'1222\'11111'
,則等同於"1222'11111"
'A'#
表示這個字元的ASCII值,也就是65'UTF16字串'u
表示UTF-16 LE編碼的字串- 檔案路徑引號前加$符表示編譯後將檔案嵌入到exe中,載入dll時經常會用到
全域性函式
Python中有str
、int
、print
這些可以使用的全域性函式,aardio中也內建了一些可以全域性使用的函式。我覺得用不到的就不在下面列出來了
tostring
- 將某個值轉換為字串,如果是物件則呼叫
_tostring
元方法。 - 第二個引數可以指定進位制,比如
tostring(10, 16)
返回0xA
- 如果第一個引數是時間,則第二個引數可以指定格式化時間的字串,比如
tostring(time(), "%Y-%m-%d %H:%M:%S")
topointer
將引數轉換為指標,這個函式我還沒用過。到時候用的時候再看什麼作用
tonumber
- 將某個值轉換為數值,如果是物件則呼叫
_tonumber
元方法。 - 如果是指標則返回記憶體地址
- 如果是字串, 第二個引數可以指定進位制,例如
tonumber("0xA", 16)
注意: 這個函式會返回兩個值,第一個是轉換後的數值。第二個是轉換使用的字元數。例如tonumber("12a")
, 返回12和2.
一般會使用兩個值接收var a, b = tonumber("12a")
invoke
invoke(被呼叫函式, owner, 引數1, 引數2)
呼叫指定函式,owner這個後面再提
call
call(被呼叫函式, owner, 引數)
呼叫指定函式,跟invoke基本類似
callex
callex(異常處理函式,被呼叫函式, owner, 引數)
當被呼叫函式程式碼出現異常時則呼叫異常處理函式
loadcode
載入編譯程式碼,引數可以是程式碼字串或者程式碼路徑
loadcodex
載入編譯和執行程式碼,引數可以是程式碼字串或者程式碼路徑
dumpcode
編譯程式碼為二進位制位元組
sleep
同步阻塞休眠,和Python的time.sleep一樣,單執行緒情況下會卡住介面。介面中應使用win.delay
type
用於獲取物件的資料型別,一般使用type(obj) == type.string
來判斷物件是不是字串,所有型別請看基礎語法中的基本資料型別
eval
執行aardio程式碼,並返回表示式的值
error
主動丟擲異常
參考
- [1] aardio官方文件:
https://bbs.aardio.com/doc/reference/
- [2] 標準內碼表(codepage)列表:
https://blog.csdn.net/jianggujin/article/details/80325461
- Python所有全域性函式:
https://mp.weixin.qq.com/s/PA0lsojc-zkZ4eltj8P6Kg
本文由部落格一文多發平臺 OpenWrite 釋出!