aardio教程一) 基礎語法-上

前言

想開發一些小工具,所以想系統性的學習一遍aardio,之前都是哪裏不會搜哪裏,順便寫些教程。我的主要語言是Python,所以會以Python作爲對比來加深印象。

aardio的基礎語法和JavaScript基本類似,如果你學過JavaScript,aardio很容易上手。下面的文檔來自官方文檔 [1]

問題搜索途徑

基礎語法看:https://bbs.aardio.com/doc/reference/

一些庫的使用,獲取文檔有以下途徑:

  1. aardio官方論壇(https://bbs.aardio.com),我一般用谷歌搜索 site:bbs.aardio.com 搜索內容
  2. aardio官方公衆號
  3. 打開編輯器開始頁的話有開發指南和文檔資源,右側有官方資訊,剛入門都可以看一下。裏面的庫函數文檔我經常用
  4. 寫一個函數的時候右鍵轉到定義,庫代碼下面一般都有註釋怎麼用
  5. 用vscode打開整個aardio軟件目錄,搜索你不知道怎麼用的庫,看看官方是怎麼使用的,這個我用的最多
  6. 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 2b = 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, nullfalse 相等,其他類型都與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中有strintprint 這些可以使用的全局函數,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 發佈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章