Wang BASIC

Wang BASIC
Utvecklare Wang Laboratories
Dök först upp 1973 ; 50 år sedan ( 1973 )
Influerad av
Dartmouth BASIC

Wang BASIC är en serie BASIC-programmeringsspråk för datorer från Wang Laboratories . Termen kan användas för att hänvisa till BASIC på vilken Wang-maskin som helst, men är mest förknippad med versionerna på Wang 2200 - minidatorserien från början av 1970-talet. När dessa maskiner uppdaterades till VP-serien 1976, introducerades BASIC-2 och förblev mönstret för framtida maskiner i 2200-serien. En planerad BASIC-3 släpptes aldrig.

Wang erbjöd flera modeller av varje version av 2200-serien, som endast skilde sig åt i mängden mikrokod lagrad i läsminne (ROM), och därmed antalet kommandon tillgängliga i BASIC på den maskinen. Till exempel skilde sig B-modellmaskinerna från basmodellen A genom att dubbla ROM och använda den för att lagra en mängd olika in-/utdata- och filhanteringskommandon.

Wang BASIC följde nära den ursprungliga Dartmouth BASIC i syntax, men var en tolk i motsats till ett kompilera-och-gå- system. En anmärkningsvärd egenskap var att all matematik använde dubbelprecision binärkodat decimalformat (BCD), vilket var ovanligt för erans BASICs. Det saknade många funktioner som är gemensamma för senare dialekter som Microsoft BASIC , men många av dessa funktioner lades till i BASIC-2.

Beskrivning

Följande beskrivning är baserad på den ursprungliga BASIC som finns i 2200A. Inte alla instruktioner som anges nedan skulle vara tillgängliga i basmodellen; 2200B och C har lagt till dussintals nya sökord och beskrivs separat nedan.

Programredigering och exekvering

Den ursprungliga Wang BASIC för 2200 är en relativt standardversion av Dartmouth BASIC- konceptet och kommer att vara bekant för användare av alla vanliga BASIC-tolkar som Microsoft BASIC . Liksom de flesta BASIC-tolkar, fungerade Wang BASIC i omedelbart läge eller programläge , och växlade till det senare när ett linjenummer ses i början av raden när EXEC- tangenten (retur) trycks ned. Radnummer varierade från 0 till 9999. Rader kan bestå av upp till 192 tecken, spänner över flera rader på skärmen, och rader kan innehålla flera påståenden separerade med kolon. För att hjälpa till att organisera stora program inkluderade språket ett RENUMBER- kommando.

LIST användes för att visa programmets källkod, medan LIST S endast visade de första 15 raderna och sedan pausades. När den pausades visades nästa 15 rader genom att trycka på EXEC-tangenten. SAVE "filename" sparade det aktuella programmet på kassett och LOAD "filename" läste in det igen. SKIP 2F läste över de kommande två filerna som fanns på kassettbandet och stoppade sedan, så att en efterföljande LOAD eller SAVE kunde fungera på den tredje fil. BACKSPACE var motsatsen till SKIP, spola tillbaka filpekaren. Arbetet med disklagring var något mer komplext, med LOAD DC F "filnamn" , där F syftade på en av ett antal fördefinierade enheter, i det här fallet "Fixed".

RUN startade exekveringen och kunde dirigeras till en viss linje, som i RUN 100 . Kommandot STOP , som vanligtvis används för felsökning, tillät en valfri följande sträng som skrevs ut när den satsen utfördes. TRACE kunde användas för att skriva ut rader när de kördes, vilket ofta användes i kombination med de anpassade HALT (break) och STEP- tangenterna på tangentbordet för att flytta rad för rad genom ett program. SELECT P användes för att ställa in en fördröjning mellan TRACE -linjer i enheter på 1 6 sekund; SELECT P0 ställer in fördröjningen till noll, SELECT P3 gör att den pausar 1 2 sekund efter varje rad.

Det fanns inget NEW- kommando för att rensa minnet i ett befintligt program, istället använde ett CLEAR för att återställa minnet. CLEAR P (för "P"rogram) var motsvarigheten till NEW men lades till valfria från och till radnummer, och raderade just det radintervallet på ett sätt som liknar kommandot DELETE som finns i vissa dialekter. CLEAR V rensar ut variabelvärden, som normalt åstadkommes av CLR i de flesta dialekter. CLEAR N liknade CLEAR V, men rensade inte värdet av delade variabler (se nedan).

Syntax

Förgrening stöddes genom IF...THEN , GOTO och GOSUB . Det alternativa formuläret GÅ TILL stöddes inte. En begränsning av Wang BASIC, som i fallet med den ursprungliga Dartmouth också, är att THEN-satsen i en IF-sats bara kan vara ett radnummer, i motsats till mer moderna dialekter som tillåter vilket påstående som helst efter THEN. Det saknade också booleska konjunktioner som AND eller OR , så testet kunde bara ha en enda jämförelse.

Ett intressant tillägg till språket var idén om namngivna rutiner. Implementeringen baserades på DEF FN -satsen följt av ett enda citat och sedan ett tal från 0 till 255, till exempel DEFFN' 1 . Detta kan sedan anropas med GOSUB '1 . För att ytterligare förvirra saken var DEFFN-raden en sann funktionsdefinition och kunde använda parametrar, som DEFFN'5(A$, N) , som kunde anropas med GOSUB'5("hej", 4) . In låter en implementera flerradsfunktionsdefinitioner, som andra dialekter ibland erbjöd med den konventionella funktionsstilen snarare än att använda GOSUB. Dessutom tilldelades namngivna rutiner i intervallet 0 till 31 till de liknande numrerade tangenterna på 2200-tangentbordet, vilket gjorde att de kunde anropas direkt med en enda knapptryckning.

PRINT stödde komma- och semikolonseparerande parametrar, den förra flyttar markören till nästa 16 tecken breda kolumn, den senare lämnar markören i slutet av det utskrivna värdet. Den stödde TAB() men inte SPC() . I likhet med andra "high end" BASICs från eran, erbjöd Wang BASIC formaterad utdata med PRINTUSING och en separat "bild". Bilden definierades med en separat rad som börjar med procenttecknet, till exempel 180 % ##,###.## och sedan med det formatet med 190 PRINTUSING 180, N . Alla andra tecken än formateringstecknen återkom under utskriften, så man kunde definiera en komplett utdata med ungefär 180 % ANGLE= #.#### RADIANS .

INPUT- satser kan innehålla en prompt tillsammans med en kommaavgränsad lista med en eller flera variabler. Semikolon kunde inte användas i INPUT, och markören stod alltid kvar i slutet av det senast utskrivna elementet under inmatningen.

Matematik och logik

Liksom de flesta dialekter av eran, kunde variabelnamn bestå av en enda stor bokstav eller en bokstav följt av en enda siffra. Det stödde inte namn med två bokstäver. Flera variabler kan ställas in på ett initialt värde med hjälp av en kommaseparerad lista, till exempel LET A,B,C=1 . Som med de flesta BASICs var LET alltid valfritt. Variabler kunde göras till listor (endimensionella arrayer) med DIM , som i DIM A(5) som gjorde en lista med 5 numeriska värden. eller tvådimensionella arrayer som använder DIM B(5,5) .

Relationella operatorer inkluderade standarduppsättningen = , < , > , <> , <= och >= . Trigonometriska funktioner inkluderade SIN , COS , TAN , ARCSIN , ARCCOS , ARCTAN , LOG , EXP och SQR . ATN var ett alias för ARCTAN. Trigonometriska funktioner fungerar normalt i radianer , men kan ställas in på att använda grader med SELECT D eller gradianer med SELECT G , och återgår till radianer med SELECT R. Andra funktioner inkluderade INT , ABS , SGN , RND och #PI -pseudovariabeln.

Till skillnad från de flesta BASIC, behandlade RND -funktionen inte parametern som en platshållare; vilket värde som helst som inte var noll fick det att fungera som RND som ses i andra BASICs, medan ett värde på noll startade om nummersekvensen på samma sätt som RANDOMIZE-satsen i andra BASICs. Detta är en potentiell källa till buggar vid portering från andra dialekter, som i allmänhet ignorerade parametern och ofta använde noll som parameter helt enkelt som en vanlig platshållare.

Strängar

Strängvariabler stöddes och sammanlänkning stöddes med hjälp av plusoperatorn. I motsats till senare BASICs som använde dynamiska längdsträngar på en hög, som Microsoft, satte Wang BASIC alla strängar till en standardlängd på 16 tecken och skulle ignorera alla tecken som tilldelats utöver det. Oanvända tecken i slutet av en sträng fylldes med mellanslagstecken, och eventuella efterföljande mellanslag ignorerades i PRINT-satser, vilket är en annan potentiell källa till problem vid portering av kod till Wang BASIC.

Lagringslängden för en enskild sträng kan ändras med hjälp av DIM- satsen, som i det här fallet använde den något udda syntaxen att sätta längden omedelbart efter variabelnamnet, som DIM A$40 , istället för att använda parens som i en typisk DIM-sats. Strängar hade en maximal längd på 64 tecken. Syntaxen tillät listor med strängar, till exempel DIM A$(5) gjorde en lista med 5 strängar med standardlängden på 16 tecken, medan DIM B$(10)20 gjorde en lista med 10 strängar med 20 tecken.

Det fanns en liten uppsättning strängfunktioner. STR är ett allmänt array-slicing- kommando som ersätter DEC/Microsoft-stilen MID / LEFT / RIGHT . Till exempel STR(B$,10,5) de fem tecknen i A$ med början vid tecken 10. Den andra parametern var valfri, STR(C$,5) returnerade allt från och med det 5:e tecknet. LEN returnerade längden på strängen och ignorerade efterföljande mellanslag, så LEN("ABC ") skulle returnera 3. För att ytterligare förvirra saken returnerade tomma strängvariabler alltid längden 1. Observera att strängfunktionerna inte inkluderar $, i i motsats till de flesta BASICs där dessa funktioner skulle heta STR$ , till exempel, vilket anger att returvärdet är en sträng, inte ett numeriskt värde.

Data och I/O

I enlighet med Dartmouth-modellen inkluderade Wang BASIC DATA- satser för att lagra konstanter i programkoden, och dessa lästes med READ -satsen, som startade vid det första dataelementet och sedan flyttade en pekare framåt till nästa element med varje READ. RESTORE kunde återställa READ-pekaren och utökades från den ursprungliga Dartmouth-versionen genom att tillåta pekaren att ställas in på ett visst objekt i listan, till exempel RESTORE 10 , som satte den till det 10:e elementet. Endast 256 värden kunde anges i DATA-satser totalt i ett program.

SELECT - satsen kan användas för att omdirigera utdata från andra BASIC-kommandon till andra enheter, baserat på enhetens "adress". Till exempel SELECT PRINT 215 skicka utdata från efterföljande PRINT-satser till skrivaren på adress 215, medan SELECT PRINT 005 returnerade utdata till den inbyggda CRT. SELECT LIST 215 skulle göra samma sak för alla följande LIST-satser. SELECT hade också en valfri följande parameter för att ställa in den maximala radlängden, som SELECT PRINT 215 (132) . Man skulle kunna använda SELECT med en mängd olika fördefinierade enheter, som CI för "konsolingång" (normalt tangentbordet) eller LIST för att omdirigera programlistan till en annan enhet.

Kedja program

Eftersom maskiner från eran hade mycket begränsade mängder minne, inkluderade de flesta dialekter av BASIC något sätt att "kedja" ihop program för att tillåta att ett enda program kan delas upp i mindre moduler. I Wang BASIC åstadkoms detta med COM- och LOAD -satserna.

COM förklarade att en eller flera variabler var "vanliga" eller globala i modern terminologi. Ett program som använder kedja skulle vanligtvis deklarera ett antal variabler som vanliga nära toppen av koden, kanske COM A,B,I,A$20 . När en separat programmodul laddas kommer värdena i dessa variabler inte att raderas, till skillnad från de icke-vanliga variablerna som kommer att återställas. Vanliga variabler skulle kunna rensas explicit med CLEAR V , medan CLEAR N rensar icke-vanliga variabler och lämnar vanliga variabler ifred. Variabler kan också förklaras icke-vanliga med COM CLEAR , som återställer alla vanliga variabler till normala, eller COM CLEAR A för att återställa bara statusen för A. Förvirrande nog återställer COM CLEAR även alla andra COM-variabler definierade före A, så resultaten av COM CLEAR A skulle vara annorlunda om det ursprungliga programmet använde COM S,B,A eller COM A,B,S , i det första exemplet skulle alla tre återställas medan i det andra endast A skulle återställas.

Kommandot LOAD användes också för kedja. Man kan valfritt lägga till start- och slutradnummer, i vilket fall eventuella befintliga rader mellan dessa gränser skulle raderas, eller från startraden till slutet av programmet om bara ett nummer anges. Det nya programmet laddas sedan vid den punkten och exekveringen startar vid startradsnumret, eller start av programmet om ingen startlinje specificerats.

Variationer på 2200 BASIC

Den ursprungliga Wang BASIC kom i flera versioner som skilde sig i mängden ROM-baserad mikrokod, och därmed antalet nyckelord som stöds.

2200B

BASIC i 2200B var en stor expansion av 2200A-versionen. Tilläggen kan generellt delas in i fyra kategorier; saknade funktioner, ytterligare strängkommandon, vektorliknande kommandon och input/output. Skillnaderna mellan versionerna finns i tabellform i 2200-översiktsdokumentet.

Saknade funktioner som togs upp i 2200B inkluderar tillägget av ON...GOTO och ON...GOSUB . KEYIN läser ett tecken från tangentbordet utan att pausa, liknande INKEY$ i MS BASIC. VAL sökte efter en sträng och returnerade ett numeriskt värde inom den. Funktionen NUM liknade LEN, men returnerade längden på delsträngen upp till det första icke-numeriska tecknet. Till exempel, om A$ är "1234.5", skulle NUM(A$) returnera 6, medan om A$ var "1234.5" skulle NUM returnera 10, eftersom mellanslag är giltiga i siffror.

2200B lade inte till en STR$-funktion, som konverterar ett numeriskt värde till en sträng. Istället lade de till CONVERT för att läsa strängar till siffror och vice versa. Om du till exempel använder A$ ovan, KONVERTERA A$ TILL B resultera i att B innehåller värdet 1234,5, medan KONVERTERA 123 TILL B$ skulle lämna B$ med något i stil med "123". Dartmouth BASIC inkluderade ett CHANGE-kommando men det var väldigt olika i syfte, i Dartmouth CHANGE A$ TO B producera en array av värden i B, där varje element innehåller ASCII-koden för motsvarande tecken i A$; i detta fall skulle B innehålla 49,50,51,52,46,53, ASCII-värdena för tecknen "1234.5". Wangs CONVERT hade också ett andra läge som tog en formatspecifikator som PRINTUSING och använde den för att konvertera ett tal till en formaterad sträng på ett sätt analogt med C :s sprintf .

POS - funktionen returnerar indexet för ett givet tecken i en sträng; POS("HELLO WORLD", "L") skulle returnera 3. I motsats till MS:s INSTR kunde POS söka efter endast ett enda tecken, inte en flerteckensträng.

HEX konverterade ett hexadecimalt värde till motsvarande tecken. Till exempel A$=HEX(20) sätta ett blanksteg (hex 20) i det första tecknet i A$. Flera koder kan infogas samtidigt; PRINT HEX(080809) producerar tre tecken, två backsteg och en högermarkör. HEX är motsvarigheten till ASC-funktionen som finns i de flesta BASICs, men använder en hex-indata istället för ett decimaltal. BIN gjorde samma sak för binära tal.

Ett specialkommando lades till för att fylla i en sträng med ett initialt värde som inte är ett mellanslag. INIT ("X") A$ skulle fylla A$ med X tecken, medan INIT (41) B$ skulle sätta hex-värdet 41, tecknet A, i B$.

2200B inkluderade också ett antal kommandon som fungerade på ett vektorliknande sätt för att utföra vanliga uppgifter som normalt skulle utföras med hjälp av en loop, eller i Dartmouth-versioner, matrismatriskommandon. Till exempel ADD en lista med uttryck, la ihop dem och returnerade resultatet. Detta åstadkoms mycket snabbare än samma uttryck med ett infix-uttryck; A=ADD(B,C,D) skulle slutföras snabbare än A=B+C+D . Liknande kommandon var OR , AND och XOR .

Majoriteten av tilläggen i 2200B var relaterade till input/output, och mest till att arbeta med diskettfiler. Det introducerade konceptet att ha flera olika filtyper, inklusive datafilen, indikerade genom att prefixet "DA" på filkommandona. En mängd andra kommandon stöddes att arbeta med dessa filer, inklusive COPY för att duplicera en fil, FLYTTA i en fil, VERIFIERA filer och SCRATCH för att radera en fil eller SCRATCH DISK för att radera allt.

2200C

Till skillnad från 2200B-versionen, som var en stor expansion på 2200A, var 2200C mycket mer begränsad i omfattning. Den lade till COM CLEAR för att rensa delade variabler, en version av DEFFN' som returnerade hex, RETURN CLEAR användes för att "poppa" en GOSUB från stacken och ON ERROR för att fånga fel i programmet.

2200T

Senare modeller i serien lade till några eller alla kommandon i B- eller C-versionerna, men bara 2200T utökade dem. Mest anmärkningsvärt i expansionerna var tillägget av matrismatte, men några I/O-detaljer lades också till.

Matriskommandona var i stort sett identiska med de som hittades i senare utgåvor av Dartmouth BASIC. Dessa tog vanligtvis formen av en uppgift, som LET, men ersatte LET med MAT . Till exempel MAT A=B+C producera en matris A vars element var summan av motsvarande element i matris B och C. Andra matriskommandon inkluderar INV ert, IDN för identitetsmatrisen och ZER för nollmatrisen och olika verktyg som COPY , MERGE , MOVE och SORT .

BASIC-2

Introduktionen av 2200VP:s helt nya instruktionsuppsättning krävde att en helt ny BASIC skulle skrivas från grunden. Även om bakåtkompatibilitet var det primära målet, lade den nya BASIC-2 också till ett antal saknade funktioner. Den mest anmärkningsvärda förändringen var att BASIC inte längre lagrades i skrivskyddat minne (ROM) och istället laddades från disken vid uppstart, vilket gjorde att den enkelt kunde patchas i fält för att fixa buggar. Det var också mycket snabbare, cirka åtta gånger, på grund av fokus på prestanda snarare än storlek, och VP-plattformens bättre prestanda.

IF-satser var begränsade i originalversionen och förbättrades avsevärt i BASIC-2. Booleska konjunktioner lades till, vilket tillät mer komplexa tester som OM X = 5 OCH Y = 10 ... Uttrycket efter THEN behövde inte längre vara ett underförstått GOTO, vilket tillåter vanliga påståenden som OM X = 10 SKRIV UT " DET ÄR TIO " . En ELSE- sats lades till och måste följa ett kolon; OM X = 10 SKRIV UT "DET ÄR TIO" : ANNARS SKRIV UT "DET ÄR INTE TIO" . ELSE kan också användas med ON-satser; X GÅ TILL 10 , 20 , 30 : ANNAT 100 skulle förgrena sig till raderna 10, 20 eller 30 om värdet i X var 1, 2 eller 3, medan vilket annat värde som helst skulle förgrenas till 100.

Nya funktioner inkluderar FIX , som alltid avrundade mot noll istället för INT som alltid avrundade nedåt; FIX(-4,5) returnerar -4, medan INT(-4,5) returnerar -5. ROUND(värde,tal) liknar FIX men avrundas till den decimal som anges i den andra parametern. MOD utför heltalsdivision och returnerar resten. MAX(a,b,c...) och MIN(d,e,f...) returnerade värdet bland listan över ingångar med det högsta eller lägsta värdet. LGT returnerar bas-10-loggen för värdet. VER kontrollerar om strängen i den första parametern matchar formatet i den andra, formatet var detsamma som PRINTUSING.

PRINTUSING kunde nu mata ut till en sträng; UTSKRIFT TILL A$, "#.##", SQR(3) skulle formatera kvadratroten ur tre till två decimaler och sätta resultatet i A$. Flera nya pseudofunktioner lades till PRINT; AT (X,Y) -funktionen liknade i konceptet TAB, men flyttade markören till X,Y-platsen, BOX(W,H) ritade en ruta med given bredd och höjd med det övre vänstra hörnet vid den aktuella markören position, och HEXOF(v) returnerade hex-värdet.

Standardsträngstorleken ändrades inte, men den maximala storleken ökades från 64 till 124 tecken. Maximala arraydimensioner ökade från 255 till 65535 element.

BASIC-3

I mars 1977 tillkännagav Wang en utökad version av VP-systemet som inkluderade mer minne, upp till 256 KB, och ett terminalserversystem för att tillåta en enda maskin att stödja upp till tolv terminaler. Känd som 2200MVP, de första enheterna skickades i januari 1978. LVP-modellerna för fyra användare och SVP-en för en användare av samma maskin levererades 1980.

Den 2 april 1981, på Hannovermässan, tillkännagav Wang en stor uppdatering av MVP-seriens mikrokod. Alternativet $2 000 "C" lade till en COBOL- kompilator samt en ytterligare uppdaterad version av BASIC, BASIC-3. Då förväntade de sig att släppa den i betaform i augusti och för alla kunder i november. Systemet skickades till ett litet antal webbplatser för betatestning, men släpptes aldrig.

Anteckningar

Citat

Bibliografi