aardio教程一) 基礎語法-上

Python成长路發表於2024-03-15

前言

想開發一些小工具,所以想系統性的學習一遍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 釋出!

相關文章