De taal BASIC

Het klassieke BASIC-dialect van aukimi: types, structuren, de twee snelkoppelingen, en de regels die iedereen vangen. 2 237 commando's erachter.

In het kort#

Aukimi levert een klassiek BASIC-dialect: een volledige taal, geen speelgoed-macrosysteem, met getypeerde numerieke waarden, records, methoden, referenties, gestructureerde fouten, coroutines en WebGPU-compute. Het leeft in de TXT-viewportmodus van de Engine en in de BASIC-weergave van de scripteditor.

JavaScript blijft de canonieke scripting-API. BASIC is een optionele frontend: beide compileren naar dezelfde private dispatcher, dus een BASIC-programma en een JavaScript-programma bereiken precies dezelfde engine. Niets is tweederangs, en niets is een aparte runtime.

De regel die iedereen vangt#

Een commando-aanroep draagt altijd haakjes.

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

Dit is geen stijlkwestie. Het is wat de compiler een commando van een variabele laat onderscheiden, en het is waarom een typefout nu al bij het compileren wordt gevangen:

U schrijftWat vroeger gebeurdeWat er nu gebeurt
SpritePositon(1, 10, 20)compileerde zonder problemen, de sprite bewoog niet, en de fout kwam pas later naar boven als ... is not definedcompilerfout, met de dichtstbijzijnde gecatalogiseerde spelling als suggestie
Blorp(1, 2)letterlijk doorgestuurd naar de gegenereerde JavaScriptcompilerfout
ceci nest pas du basicuitgezonden als een statementcompilerfout

Een schrijffout deed zich vroeger voor als een enginebug. Gemeten aan het corpus van 84 demo's leverde de bewaker nul valse positieven op en vond ze twee echte stille fouten, SetMusicSystemVolume en GetLightSensorExists, die de catalogus alleen kent als MusicSystemVolume en LightSensorExists.

Twee lekken zijn bewust opengelaten: console.log("x") en window.x = 1 komen nog altijd door. Er werd een bewaker voor geschreven, gemeten en teruggetrokken: BASIC draait binnen een context die namen aanlevert die de compiler niet kan opsommen, dus het weigeren van een onbekende wortel wees geldige programma's af. Een valse positieve daar is erger dan het lek.

De meest voorkomende verrassing:

Print(...)tekent op het scherm, en een programma roept het elke frame aan
Console(...)schrijft naar de console van de editor, en doet verder niets
Debug(...)hetzelfde commando onder de naam van PureBasic, voor het spiergeheugen
ConsoleWarning, ConsoleError, ClearConsolede rest van het logboek

Print in een framelus zou elke echte fout in de console verdrinken, daarom zijn de twee aparte commando's in plaats van één met een vlag.

Types#

Numerieke types zijn echt, en gedragen zich identiek op elk doel: de editor, de HTML-export en de Bevy-/native-build.

  • Ondertekende en niet-ondertekende 8-, 16-, 32- en 64-bit gehele getallen, met deterministische dwang, gehele DIV, en overloop door wrapping.
  • float32 en float64.
  • De klassieke sigils werken nog altijd: name$ is een string, speed# een float.

OPTION EXPLICIT is opt-in, en klassieke impliciete variabelen blijven standaard zodat geïmporteerde programma's blijven draaien. Het inschakelen ervan is de voorwaarde voor de twee functies die niet veilig kunnen zijn zonder: numerieke typering en referenties, omdat een verkeerd gespelde toewijzing die stilzwijgend een variabele aanmaakt, beide ondermijnt.

Structuren#

Records#

TYPE declareert een record. Ze nesten willekeurig, en ze hebben waardesemantiek: er één toewijzen kopieert diep, inclusief geneste arrays en collecties.

Methoden#

METHOD bindt een functie aan een instantie, met SELF erbinnen, New om te construeren en Delete om te vernietigen. Diepe kopieën blijven methodeveilig.

Referenties#

REF en BYREF zijn hetzelfde ding onder twee spellingen, en beide geven een levende lees-/schrijfparameter, voor een scalair, een record, een enkel veld, een array, een lijstcursor of een map-item. Referenties reizen mee door aanroepen heen, en dwingen zich bij de grens naar types met vaste breedte.

Handles#

@target neemt een eersteklas referentie. HANDLE en POINTER zijn de getypeerde vormen, met gecontroleerd lezen, schrijven, geldigheid en vrijgave, en een handle naar een verwijderd record wordt ongeldig gemaakt in plaats van bungelend achtergelaten.

Controle en veiligheid#

Gestructureerde fouten: TRY / CATCH / FINALLY, genest, met THROW, beveiligde RETHROW, en zowel gestructureerde als string-catches.

Voorwaardelijke compilatie: #IF / #ELSEIF / #ELSE / #ENDIF, genest, met featurevlaggen en expliciete profielen voor de editor, HTML, Bevy, native/wasm en debug/release. Ze wordt opgelost vóór includes, op elk doel.

Rijke functies: standaardwaarden, OPTIONAL, een afsluitende PARAMARRAY (of ...), veilige ariteitsoverloads, getypeerde retourdwang, en gekloonde record- en arrayretourwaarden.

Programma's met meerdere bestanden#

#INCLUDE, #INSERT en IncludeFile maken van een programma meerdere bestanden. De editor maakt en importeert projectmodules, vult includepaden aan, houdt de afhankelijkheidsgraaf bij, en elk runtime-doel is ervoor bekabeld.

Coroutines, en wat er bewust is weggelaten#

Coöperatieve taken zijn label-gebaseerd, met getypeerde handles, een resultaat- en foutstatus, annulering bij yields, en awaits op één taak of een groep. Ze delen de gamescheduler op elk doel.

Threads met gedeeld geheugen zijn bewust uitgesloten. Niet "nog niet", uitgesloten. Een coöperatieve scheduler waarover u kunt redeneren, is beter dan een datarace die u niet kunt reproduceren.

WebGPU-compute#

Getypeerde f32 / i32 / u32 storage buffers, ruwe WGSL-pipelines, frame-geordende dispatch en memblock-terughaling, echte GPU-compute vanuit BASIC.

⚠️ Alleen Engine. Het HTML-doel geeft een expliciete capaciteitsfout, en het Bevy-doel meldt de onverenigbaarheid vóór de build in plaats van een binary te produceren die faalt bij de eerste dispatch.

Twee snelkoppelingen voor hetzelfde probleem#

597 van de commando's heten Set/Get<Object><Property>: Sprite 66, Tween 58, Text 32, Edit 29. De naam van het object zit in de functienaam en zijn id is het eerste argument van elke regel. Beide snelkoppelingen hieronder verwijderen die herhaling, en geen van beide is een nieuwe API: de compiler herbouwt de echte commandonaam en zoekt hem op in de catalogus.

WITH <family>, binnen een blok#

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

Aan het begin van een statement schrijft \prop; overal elders leest het. Positie beslist, dus er is geen tweede notatie om te leren. WITH hero, één token, blijft het recordblok; WITH SPRITE s selecteert een familie uit de catalogus.

s.position(...), overal elders#

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)

De familie komt van Create<F> / Load<F> / Clone<F>, of van een expliciete s AS Sprite wanneer de id ergens anders vandaan komt. Alleen variabelen waarvan de familie bekend is, worden herschreven: records houden hun velden, lijsten houden hun methoden, SELF.field blijft onaangeraakt.

⚠️ Een getypeerde parameter wordt niet herkend. FUNCTION move(s AS Sprite) geeft s geen familie, de pas leest alleen declaraties en toewijzingen op statementniveau. Hier vermeld omdat het een echte grens is, geen bug om op te sporen.

⚠️ De catalogus laat het werkwoord vallen bij eigenschappen, en houdt het bij levenscyclus. SpritePosition schrijft, SpriteX leest, en geen van beide draagt een Set of een Get: 4 commando's in de hele catalogus beginnen met Set, en geen enkele begint met Get. Het werkwoord overleeft waar iets ontstaat of eindigt: CreateSprite, LoadImage, DeleteSprite.

Dat is het weten waard omdat een typefout een compilerfout is, en Set… is de typefout waarmee mensen aankomen. De catalogus is de autoriteit, en de referentie wordt ervan gegenereerd.

Stringinterpolatie, opt-in#

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

{{ en }} schrijven letterlijke accolades.

⚠️ Het $-voorvoegsel is verplicht, en geen versiering. Elke letterlijke tekst interpoleren brak handgeschreven JSON, wat de world-API routinematig aanneemt:

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

Daar zijn de accolades data, geen holtes. Een niet-voorvoegde string blijft onaangeraakt, wat ze ook bevat.

Benoemen is tonen#

Een klassiek programma maakt honderden objecten. Alleen degene die het BENOEMT, komen in de Scene Graph terecht, SpriteName(id, "player") en zijn verwanten zijn wat een object in de boom zet waar de rest van de Engine het kan zien. LightName en ParticlesName doen hetzelfde voor een licht en een emitter.

De tutorial Benoem wat uw programma maakt doorloopt dit: dezelfde scène, eenmaal met de boom leeg en eenmaal met drie items erin.

De commandocatalogus#

2 237 commando's, 2 550 publieke overloads, 43 categorieën. De grootste:

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 en Compute zijn de eigen toevoegingen van Aukimi aan het klassieke dialect: de consolecommando's, het benoemen van objecten, en de WebGPU-pipeline.

De volledige commandoreferentie somt ze allemaal op, met elke parameter en elke overload, en met een eigen zoekfunctie, gegenereerd uit dezelfde catalogus die deze pagina telt, zodat ze er niet achterop kan raken. Het eigen API-paneel van de editor leest diezelfde catalogus.

Deze pagina documenteert de taal; die andere documenteert de commando's.

Grenzen en veelvoorkomende valkuilen#

  • Haakjes zijn niet optioneel bij een commando. De kale PureBasic-vorm (Debug "x") wordt geweigerd, omdat ze de variabele/commando-ambiguïteit heropent waarop de compiletime-bewaker steunt.
  • Een gebruikersfunctie wint van een gecatalogiseerd commando met dezelfde naam, en een variabele mag de naam van een commando delen in een getypeerde declaratie, links van een toewijzing, of als de wortel van een pad.
  • Variabelen en gebruikersfuncties zijn hoofdletterongevoelig, en hun symboolruimtes staan werkelijk los van die van de catalogus.
  • Print is geen log. Zie hierboven; het is de fout die een console vult.
  • Compute exporteert niet. Schrijf het terugvalpad voordat u erop vertrouwt.