Ngôn ngữ BASIC
Dialect BASIC cổ điển của aukimi: kiểu dữ liệu, cấu trúc, hai lối viết tắt, và những quy tắc bẫy mọi người. 2 237 lệnh đứng phía sau.
Trong một câu#
aukimi đi kèm một dialect BASIC cổ điển: một ngôn ngữ đầy đủ, không phải
một hệ thống macro đồ chơi, với kiểu số có kiểu tường minh, record, method,
tham chiếu, lỗi có cấu trúc, coroutine và tính toán WebGPU. Nó sống trong chế
độ viewport TXT của Engine và trong view BASIC của trình biên tập script.
JavaScript vẫn là API script chính thống. BASIC là một frontend tuỳ chọn: cả hai đều biên dịch về cùng một bộ điều phối riêng, nên một chương trình BASIC và một chương trình JavaScript đến cùng một engine y hệt nhau. Không có gì là hạng hai, và không có runtime thứ hai nào cả.
Quy tắc bẫy mọi người#
Một lệnh gọi luôn mang theo dấu ngoặc đơn.
mode = ClipSpaceMode()
SpritePosition(player, 320, 180)
Đây không phải chuyện phong cách. Đó là điều cho phép trình biên dịch phân biệt một lệnh với một biến, và đó là lý do một lỗi chính tả giờ đây bị bắt ngay lúc biên dịch:
| Bạn viết | Điều từng xảy ra | Điều xảy ra bây giờ |
|---|---|---|
SpritePositon(1, 10, 20) | biên dịch trót lọt, sprite không di chuyển, và lỗi chỉ lộ ra sau đó dưới dạng ... is not defined | lỗi biên dịch, kèm gợi ý cách viết gần nhất trong catalogue |
Blorp(1, 2) | được chuyển nguyên văn vào JavaScript được sinh ra | lỗi biên dịch |
ceci nest pas du basic | được phát ra như một câu lệnh | lỗi biên dịch |
Một lỗi viết sai từng thể hiện ra như một lỗi của engine. Đo trên bộ ngữ liệu 84 demo, lớp bảo vệ này tạo ra không một dương tính giả nào và tìm thấy hai lỗi âm thầm có thật,
SetMusicSystemVolumevàGetLightSensorExists, mà catalogue chỉ biết đến dưới tênMusicSystemVolumevàLightSensorExists.
Hai lỗ hổng vẫn được để ngỏ một cách có chủ đích: console.log("x") và
window.x = 1 vẫn qua được. Một lớp bảo vệ cho chúng đã được viết, đo lường,
và rút lại: BASIC chạy trong một ngữ cảnh cung cấp những cái tên mà trình
biên dịch không thể liệt kê hết, nên việc từ chối một root không xác định sẽ
loại bỏ luôn cả những chương trình hợp lệ. Một dương tính giả ở đó còn tệ hơn
lỗ hổng.
Print vẽ. Console ghi log.#
Điều bất ngờ phổ biến nhất:
Print(...) | vẽ lên màn hình, và một chương trình gọi nó ở mỗi khung hình |
Console(...) | ghi vào console của trình biên tập, và không làm gì khác |
Debug(...) | cùng một lệnh dưới cái tên của PureBasic, để giữ trí nhớ cơ bắp |
ConsoleWarning, ConsoleError, ClearConsole | phần còn lại của log |
Print trong một vòng lặp khung hình sẽ nhấn chìm bất kỳ lỗi thật nào trong
console, đó là lý do hai lệnh này tách biệt thay vì một lệnh có thêm một cờ.
Kiểu dữ liệu#
Các kiểu số là thật, và chúng hoạt động giống hệt nhau trên mọi target: trình biên tập, bản xuất HTML và bản build Bevy/native.
- Số nguyên có dấu và không dấu 8, 16, 32 và 64-bit, với phép ép kiểu tất
định,
DIVsố nguyên, và tràn số kiểu wrap-around. - float32 và float64.
- Các ký hiệu cổ điển vẫn hoạt động:
name$là một chuỗi,speed#là một float.
OPTION EXPLICIT là tuỳ chọn bật, và các biến ngầm định kiểu cổ điển vẫn
là mặc định để các chương trình được nhập từ nơi khác vẫn chạy được. Bật nó
lên là điều kiện tiên quyết cho hai tính năng không thể an toàn nếu thiếu nó,
kiểu số tường minh và tham chiếu, bởi một phép gán viết sai chính tả mà âm
thầm tạo ra một biến mới sẽ vô hiệu hoá cả hai.
Cấu trúc#
Record#
TYPE khai báo một record. Chúng lồng nhau tuỳ ý, và có ngữ nghĩa giá
trị: gán một record sẽ deep-copy nó, bao gồm cả mảng và collection lồng
bên trong.
Method#
METHOD gắn một hàm vào một instance, với SELF bên trong nó, New để khởi
tạo và Delete để huỷ. Các bản deep copy vẫn an toàn với method.
Tham chiếu#
REF và BYREF là cùng một thứ dưới hai cách viết, và cả hai đều cho một
tham số đọc/ghi sống động, cho một scalar, một record, một field đơn lẻ, một
mảng, một con trỏ danh sách hay một entry của map. Tham chiếu truyền tiếp qua
các lệnh gọi, và ép kiểu về kích thước cố định tại biên.
Handle#
@target lấy một tham chiếu hạng nhất. HANDLE và POINTER là các dạng có
kiểu, với đọc, ghi, kiểm tra hiệu lực và giải phóng đều được kiểm tra, và một
handle trỏ đến một record đã bị xoá sẽ bị vô hiệu hoá thay vì bị bỏ lửng.
Kiểm soát và an toàn#
Lỗi có cấu trúc: TRY / CATCH / FINALLY, lồng được, với THROW,
RETHROW được bảo vệ, và bắt được cả dạng có cấu trúc lẫn dạng chuỗi.
Biên dịch có điều kiện: #IF / #ELSEIF / #ELSE / #ENDIF, lồng được,
với cờ tính năng và các profile tường minh cho editor, HTML, Bevy, native/wasm
và debug/release. Nó được xử lý trước các include, trên mọi target.
Hàm giàu tính năng: giá trị mặc định, OPTIONAL, một PARAMARRAY (hay
...) ở cuối, overload an toàn theo số lượng tham số, ép kiểu giá trị trả về,
và record cùng mảng trả về đều được nhân bản.
Chương trình nhiều file#
#INCLUDE, #INSERT và IncludeFile biến một chương trình thành nhiều file.
Trình biên tập tạo và nhập các module dự án, tự hoàn thành đường dẫn include,
giữ đồ thị phụ thuộc, và mọi runtime target đều được kết nối cho việc này.
Coroutine, và thứ bị cố tình bỏ ra ngoài#
Các task hợp tác được đánh dấu bằng nhãn, với handle có kiểu, trạng thái kết quả và lỗi, huỷ được tại các điểm yield, và có thể await một task đơn lẻ hay một nhóm. Chúng chia sẻ chung bộ lập lịch của game trên mọi target.
Thread với bộ nhớ chia sẻ bị loại trừ một cách có chủ đích. Không phải "chưa có" mà là bị loại trừ. Một bộ lập lịch hợp tác mà bạn có thể suy luận được còn hơn một cuộc đua dữ liệu mà bạn không thể tái hiện lại.
Tính toán WebGPU#
Storage buffer có kiểu f32 / i32 / u32, pipeline WGSL thô, dispatch theo
thứ tự khung hình và đọc lại memblock, tính toán GPU thật từ BASIC.
⚠️ Chỉ dành cho Engine. Target HTML báo lỗi năng lực tường minh, và target Bevy báo sự không tương thích trước khi build thay vì tạo ra một binary lỗi ngay ở lần dispatch đầu tiên.
Hai lối viết tắt cho cùng một vấn đề#
597 trong số các lệnh có tên Set/Get<Object><Property>: Sprite 66,
Tween 58, Text 32, Edit 29. Tên đối tượng nằm bên trong tên hàm và id của nó
là tham số đầu tiên của mọi dòng. Cả hai lối viết tắt dưới đây đều loại bỏ sự
lặp lại đó, và không cái nào là một API mới: trình biên dịch dựng lại tên lệnh
thật và tra nó trong catalogue.
WITH <family>, bên trong một block#
WITH SPRITE s
\position 100, 200 ` SpritePosition(s, 100, 200)
\size 64, 64 ` SpriteSize(s, 64, 64)
x# = \x ` SpriteX(s)
ENDWITH
Ở đầu một câu lệnh \prop sẽ ghi; ở bất kỳ vị trí nào khác nó đọc. Vị
trí quyết định, nên không có ký hiệu thứ hai nào cần học thêm. WITH hero,
một token duy nhất, vẫn là block record; WITH SPRITE s chọn một family trong
catalogue.
s.position(...), ở mọi nơi khác#
s = CreateSprite(img) ` the family is DEDUCED from the creation command
s.position(100, 200) ` SpritePosition(s, 100, 200)
s.visible = 1 ` SpriteVisible(s, 1)
x# = s.x ` SpriteX(s)
Family đến từ Create<F> / Load<F> / Clone<F>, hoặc từ một khai báo tường
minh s AS Sprite khi id đến từ nơi khác. Chỉ những biến có family đã
biết mới được viết lại: record giữ nguyên field của chúng, list giữ nguyên
method của chúng, SELF.field không bị đụng đến.
⚠️ Một tham số có kiểu không được nhận diện. FUNCTION move(s AS Sprite)
không cho s một family, lượt quét chỉ đọc các khai báo và phép gán ở cấp câu
lệnh. Ghi rõ ở đây vì đây là một giới hạn thật, không phải một lỗi cần bạn đi
tìm.
⚠️ Catalogue bỏ động từ trên các property, và giữ nó trên lifecycle.
SpritePosition ghi, SpriteX đọc, và không cái nào mang Set hay Get:
4 lệnh trong toàn bộ catalogue bắt đầu bằng Set, và không lệnh nào
bắt đầu bằng Get. Động từ chỉ sống sót ở nơi có gì đó được tạo ra hoặc kết
thúc: CreateSprite, LoadImage, DeleteSprite.
Điều đó đáng biết vì một lỗi chính tả là một lỗi biên dịch, và Set… chính là
lỗi chính tả mà mọi người thường mắc phải. Catalogue là nguồn tham chiếu duy
nhất, và tài liệu tham khảo được sinh ra từ
chính nó.
Nội suy chuỗi, tuỳ chọn bật#
Print($"score: {points}") ` "score: " + Str(points)
{{ và }} viết ra dấu ngoặc nhọn theo nghĩa đen.
⚠️ Tiền tố $ là bắt buộc, và nó không phải là trang trí. Nội suy mọi
chuỗi ký tự sẽ làm hỏng JSON viết tay, thứ mà world API dùng thường xuyên:
CreateTerrain("island", "{\"preset\":\"island\",\"size\":256}")
Ở đó dấu ngoặc nhọn là dữ liệu, không phải chỗ trống cần điền. Một chuỗi không có tiền tố được giữ nguyên bất kể nó chứa gì.
Đặt tên là hiển thị#
Một chương trình cổ điển tạo ra hàng trăm đối tượng. Chỉ những cái được ĐẶT
TÊN mới vào Scene Graph, SpriteName(id, "player") và những lệnh tương tự
là thứ đưa một đối tượng vào cây nơi phần còn lại của Engine có thể thấy nó.
LightName và ParticlesName làm điều tương tự cho một ánh sáng và một
emitter.
Bài hướng dẫn Đặt tên cho những gì chương trình bạn tạo ra đi qua điều này: cùng một scene, một lần với cây trống rỗng và một lần với ba mục trong đó.
Catalogue lệnh#
2 237 lệnh, 2 550 overload công khai, 43 danh mục. Những cái lớn nhất:
| 3D | 286 | Studio | 106 | File | 61 |
| Core | 200 | Input | 95 | Memblock | 43 |
| Tweening | 149 | Input-Raw | 94 | 3D Particles | 41 |
| 3D Physics | 144 | Multiplayer | 91 | World | 40 |
| Sprite | 135 | Text | 68 | Particles | 38 |
| Platform | 111 | 2D Physics | 66 | Sound | 37 |
cộng thêm JSON (36), Image (35), Skeleton (34), XML (34), Music (29), Preference (27), Extras (21), HTTP (21), String (21), Math (19), Regular Expression (19), Video (18), Dictionary (17), Benchmarking (15), Compute (14), Date (13), Maths (12), Time (12), StringBuilder (9), Compression (7), Font (8), Error (4), Array (3), Cipher (2), Sort (2).
Studio và Compute là những bổ sung riêng của Aukimi cho dialect cổ điển: các lệnh console, đặt tên đối tượng, và pipeline WebGPU.
Tài liệu tham khảo lệnh đầy đủ liệt kê tất cả, kèm mọi tham số và mọi overload, với công cụ tìm kiếm riêng, được sinh ra từ cùng một catalogue mà trang này đếm, nên nó không thể bị tụt lại phía sau. Panel API của chính trình biên tập cũng đọc catalogue đó.
Trang này viết về ngôn ngữ; trang kia viết về các lệnh.
Giới hạn và các lỗi thường gặp#
- Dấu ngoặc đơn không phải là tuỳ chọn trên một lệnh. Dạng PureBasic trần
trụi (
Debug "x") bị từ chối, vì nó mở lại sự mập mờ biến/lệnh mà lớp bảo vệ biên dịch phụ thuộc vào. - Một hàm người dùng thắng một lệnh trong catalogue cùng tên, và một biến có thể chia sẻ tên với một lệnh trong một khai báo có kiểu, ở vế trái của một phép gán, hoặc làm root của một đường dẫn.
- Biến và hàm người dùng không phân biệt hoa thường, và không gian ký hiệu của chúng thật sự tách biệt với catalogue.
Printkhông phải là log. Xem ở trên; đó là lỗi làm đầy một console.- Compute không xuất ra được. Hãy viết lối dự phòng trước khi bạn dựa vào nó.