BASIC-sproget

aukimis klassiske BASIC-dialekt, typer, strukturer, de to genveje, og reglerne, der fanger alle. 2 237 kommandoer bag den.

I én sætning#

Aukimi leveres med en klassisk BASIC-dialekt: et fuldt sprog, ikke et legetøjs-makrosystem, med typede numeriske typer, records, metoder, referencer, strukturerede fejl, coroutines og WebGPU compute. Den lever i Engines TXT-viewporttilstand og i script-editorens BASIC-visning.

JavaScript forbliver den kanoniske scripting-API. BASIC er et valgfrit frontend: begge kompilerer til den samme private dispatcher, så et BASIC-program og et JavaScript-program når nøjagtigt den samme motor. Intet er andenrangs, og intet er en separat runtime.

Reglen, der fanger alle#

Et kommandokald bærer altid parenteser.

mode = ClipSpaceMode()
SpritePosition(player, 320, 180)

Det er ikke stil. Det er det, der lader kompilatoren skelne en kommando fra en variabel, og det er derfor, en stavefejl nu fanges ved kompilering:

Du skriverHvad der plejede at skeHvad der sker nu
SpritePositon(1, 10, 20)kompilerede rent, spritet flyttede sig ikke, og fejlen dukkede først op senere som ... is not definedkompileringsfejl, med det nærmeste katalogiserede stavemåde foreslået
Blorp(1, 2)videresendt ordret ind i den genererede JavaScriptkompileringsfejl
ceci nest pas du basicudsendt som en sætningkompileringsfejl

En skrive-fejl gav sig tidligere ud for at være en motor-fejl. Målt mod korpusset af 84 demoer producerede vagten nul falske positiver og fandt to reelle, stille fejl, SetMusicSystemVolume og GetLightSensorExists, som kataloget kun kender som MusicSystemVolume og LightSensorExists.

To lækager er bevidst efterladt åbne: console.log("x") og window.x = 1 slipper stadig igennem. En vagt til dem blev skrevet, målt, og trukket tilbage: BASIC kører inde i en kontekst, der leverer navne, kompilatoren ikke kan opremse, så at afvise en ukendt rod afviste også gyldige programmer. En falsk positiv der er værre end lækagen.

Den enkeltmest almindelige overraskelse:

Print(...)tegner på skærmen, og et program kalder den hvert billede
Console(...)skriver til editorens konsol, og gør intet andet
Debug(...)den samme kommando under PureBasics navn, for musehukommelsens skyld
ConsoleWarning, ConsoleError, ClearConsoleresten af loggen

Print i et frame-loop ville drukne enhver reel fejl i konsollen, hvilket er derfor de to er separate kommandoer i stedet for én med et flag.

Typer#

Numeriske typer er reelle, og de opfører sig identisk på hvert mål, editoren, HTML-eksporten og Bevy/native-builden:

  • Signerede og usignerede 8-, 16-, 32- og 64-bit heltal, med deterministisk tvang, heltals-DIV, og wrapping-overflow.
  • float32 og float64.
  • De klassiske sigils virker stadig: name$ er en streng, speed# er en float.

OPTION EXPLICIT er valgfrit, og klassiske implicitte variabler forbliver standarden, så importerede programmer stadig kører. At slå den til er forudsætningen for de to funktioner, der ikke kan være sikre uden den, numerisk typning og referencer, fordi en fejlstavet tildeling, der stiltiende opretter en variabel, undergraver begge dele.

Strukturer#

Records#

TYPE erklærer en record. De nestes vilkårligt, og de har value semantics: at tildele én dybdekopierer den, inklusive nestede arrays og collections.

Metoder#

METHOD binder en funktion til en instans, med SELF inde i den, New til at konstruere og Delete til at destruere. Dybdekopier forbliver metode-sikre.

Referencer#

REF og BYREF er den samme ting under to stavemåder, og begge giver en levende læse/skrive-parameter, til en skalar, en record, ét enkelt felt, et array, en liste-markør eller en map-post. Referencer videreføres gennem kald, og tvinges til fastbredde-typer ved grænsen.

Handles#

@target tager en førsteklasses reference. HANDLE og POINTER er de typede former, med tjekket læsning, skrivning, gyldighed og frigivelse, og et handle til en slettet record ugyldiggøres i stedet for at blive efterladt som dinglende.

Kontrol og sikkerhed#

Strukturerede fejl: TRY / CATCH / FINALLY, nestede, med THROW, beskyttet RETHROW, og både strukturerede og streng-baserede fangster.

Betinget kompilering: #IF / #ELSEIF / #ELSE / #ENDIF, nestede, med feature-flag og eksplicitte profiler for editoren, HTML, Bevy, native/wasm og debug/release. Den løses op før includes, på hvert mål.

Rige funktioner: standardværdier, OPTIONAL, et afsluttende PARAMARRAY (eller ...), sikre arity-overloads, typet returtvang, og klonede record- og array-returværdier.

Programmer over flere filer#

#INCLUDE, #INSERT og IncludeFile gør et program til flere filer. Editoren opretter og importerer projektmoduler, fuldfører include-stier, holder styr på afhængighedsgrafen, og hvert runtime-mål er koblet til det.

Coroutines, og det, der bevidst er udeladt#

Kooperative tasks er label-baserede, med typede handles, en resultat- og fejltilstand, annullering ved yields, og awaits på én task eller en gruppe. De deler spillets scheduler på hvert mål.

Tråde med delt hukommelse er bevidst udelukket. Ikke "endnu ikke", udelukket. En kooperativ scheduler, du kan ræsonnere om, slår en data race, du ikke kan reproducere.

WebGPU compute#

Typede f32 / i32 / u32 storage-buffere, rå WGSL-pipelines, frame-ordnet dispatch og memblock-tilbagelæsning, rigtig GPU compute fra BASIC.

⚠️ Kun Engine. HTML-målet rejser en eksplicit capability-fejl, og Bevy-målet rapporterer inkompatibiliteten før builden i stedet for at producere en binær, der fejler ved det første dispatch.

To genveje til det samme problem#

597 af kommandoerne hedder Set/Get<Objekt><Egenskab>: Sprite 66, Tween 58, Text 32, Edit 29. Objektets navn står inde i funktionsnavnet, og dets id er det første argument på hver linje. Begge genveje nedenfor fjerner den gentagelse, og ingen af dem er en ny API: kompilatoren genopbygger det rigtige kommandonavn og slår det op i kataloget.

WITH <familie>, inden i en blok#

WITH SPRITE s
  \position 100, 200      ` SpritePosition(s, 100, 200)
  \size 64, 64            ` SpriteSize(s, 64, 64)
  x# = \x                 ` SpriteX(s)
ENDWITH

I hovedet af en sætning skriver \prop; alle andre steder læser den. Positionen afgør det, så der er ingen anden notation at lære. WITH hero, ét token, er stadig record-blokken; WITH SPRITE s vælger en katalogfamilie.

s.position(...), alle andre steder#

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)

Familien kommer fra Create<F> / Load<F> / Clone<F>, eller fra en eksplicit s AS Sprite, når id'et ankommer et andet sted fra. Kun variabler, hvis familie er kendt, omskrives: records beholder deres felter, lister beholder deres metoder, SELF.field røres ikke.

⚠️ En typet parameter genkendes ikke. FUNCTION move(s AS Sprite) giver ikke s en familie, passet læser kun erklæringer og tildelinger på sætningsniveau. Nævnt her, fordi det er en reel grænse, ikke en fejl du skal jagte.

⚠️ Kataloget dropper verbet på egenskaber, og beholder det på livscyklus. SpritePosition skriver, SpriteX læser, og ingen af dem bærer et Set eller et Get: 4 kommandoer i hele kataloget begynder med Set, og ingen begynder med Get. Verbet overlever der, hvor noget kommer til verden eller ender: CreateSprite, LoadImage, DeleteSprite.

Det er værd at vide, fordi en stavefejl er en kompileringsfejl, og Set… er den stavefejl, folk ankommer med. Kataloget er autoriteten, og referencen er genereret ud fra det.

Strenginterpolation, valgfri#

Print($"score: {points}")        ` "score: " + Str(points)

{{ og }} skriver bogstavelige klammer.

⚠️ $-præfikset er obligatorisk, og det er ikke pynt. At interpolere hver eneste streng ødelagde håndskrevet JSON, som world-API'en bruger rutinemæssigt:

CreateTerrain("island", "{\"preset\":\"island\",\"size\":256}")

Der er klammerne data, ikke huller. En streng uden præfiks lades urørt, uanset hvad den indeholder.

Et klassisk program opretter hundredvis af objekter. Kun dem, det NAVNGIVER, kommer ind i Scene Graph, SpriteName(id, "player") og dens søskende er det, der sætter et objekt ind i træet, hvor resten af Engine kan se det. LightName og ParticlesName gør det samme for et lys og en emitter.

Tutorialen Navngiv, hvad dit program skaber gennemgår det: samme scene, én gang med et tomt træ og én gang med tre poster i det.

Kommandokataloget#

2 237 kommandoer, 2 550 offentlige overloads, 43 kategorier. De største:

3D286Studio106File61
Core200Input95Memblock43
Tweening149Input-Raw943D Particles41
3D Physics144Multiplayer91World40
Sprite135Text68Particles38
Platform1112D Physics66Sound37

plus 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 og Compute er Aukimis egne tilføjelser til den klassiske dialekt, konsolkommandoerne, objektnavngivningen, og WebGPU-pipelinen.

Den komplette kommandoreference viser dem alle, med hver parameter og hver overload, og har sin egen søgning, genereret fra det samme katalog, som denne side tæller, så den ikke kan komme bagud i forhold til det. Editorens eget API-panel læser også det katalog.

Denne side dokumenterer sproget; den anden dokumenterer kommandoerne.

Grænser og almindelige faldgruber#

  • Parenteser er ikke valgfrie på en kommando. Den bare PureBasic-form (Debug "x") afvises, fordi den genåbner den variabel/kommando-tvetydighed, som kompileringstidsvagten afhænger af.
  • En brugerfunktion vinder over en katalogiseret kommando med samme navn, og en variabel kan dele navn med en kommando i en typet erklæring, på venstre side af en tildeling, eller som roden af en sti.
  • Variabler og brugerfunktioner er ikke versalfølsomme, og deres symbolrum er reelt adskilt fra kataloget.
  • Print er ikke en log. Se ovenfor; det er fejlen, der fylder en konsol.
  • Compute eksporterer ikke. Skriv fallback-vejen, før du regner med den.