Startsidan  ▸  Texter  ▸  Teknikblogg

Anders Hesselbom

Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.

Vad ska språket heta?

2015-04-28

Uppdatering 2015-05-02: Språket kommer att heta Gosbust – ett genialt namn med referenser både till andra språk, populärkultur och till nyckelord i detta språk. Upphovsmannen till namnet är anonym, men har fler fyndigheter på sin meritlista, t.ex. ordet som bättre än något annat beskriver kristendomens gud Jahve – UMO (Undetectable Mythological Object).

Uppdatering 2015-05-03: Under ett tidigt stadium av språkets utveckling så skrev man A>>1 för att lagra 1 i variabeln A. Nu när Gosbust går att ladda hem är detta ändrat. Numera skriver man istället 1>>A för att lagra 1 i variabeln A. Uttrycket A>>1 ger ett kompileringsfel idag. Detta gäller för alla datatyper, och även för de underliggande instruktionerna. PUTI A 1 ska nu skrivas PUTI 1 A, där 1 är värdet som ska lagras och A är variabeln den ska lagras i.

Först och främst vill jag betona att detta språk är lite av ett terapiarbete för mig – det kommer absolut inte lösa världsproblemen eller frälsa några programmerare. Parsern är inte hierarkisk och upplägget är inspirerat av Assembler på Commodore 128. Detta innebär att språket består av instruktioner, där varje instruktion alltid tar samma antal argument. Det innebär att man inte behöver ha olika separatorer mellan argumenten och mellan programsatserna. Om ett kommando tar två argument kommer kompilatorn att läsa två argument och sedan anta att det nästa som påträffas är nästa kommando. Som separator används whitespace (blanksteg, tabb eller enterslag), och det går bra att infoga flera whitespaces efter tycke, men endast på de platser där det ska vara whitespaces. Det går inte att undvika whitespaces där whitespaces förväntas.

Följande kod placerar värdet 1 i heltalsvariabeln A, följt av en kommentar:

PUTI A 1 /* Sparar 1 i A */

Detta däremot kommer inte att fungera eftersom uttrycket 1/* inte är en giltig heltalskonstant:

PUTI A 1/* Sparar 1 i A */

Notera att variablernas datatyp härleds från deras namn. Variabler utan postfix, t.ex. A, B eller C antas vara 32-bitars heltal. Variabler vars namn slutar med $, t.ex. A$, B$ eller C$ antas vara strängar. Frågetecken betyder bit (t.ex. A?) och korsbrygga betyder flyttal (t.ex. A#).

Det finns ett enkelt syntaxlager ovanpå instruktionerna som syftar till att öka läsbarheten. PUTI A 1 kan kortas ner till 1>>A. Detta program visar de 20 första talen i Fibonacci-sekvensen (utom 0):

PUTI 1 A
GETI A
PUTI 1 B
GETI B
PUTI 0 X
PROC Run
   ADDI A B C
   GETI C
   INCI X
   SWPI A B
   SWPI B C
   LETI X 18 J?
   GOTO J? Run
GETS "Done!"

Första raden placerar 1 i variabeln A. GETI A presenterar värdet av A. PROC Run markerar starten av en subrutin som kort och gott heter Run – subrutiner kan heta vad som helst, men om namnet består av något annat än bokstäverna A-Z måste namnet kapslas in av citattecken. Subrutiner körs även om de inte blir anropade, så efter PUTI X 0 (rad 5) kommer ADDI A B C (rad 7) att köras (fallthrough). ADDI A B C sparar summan av A och B i C, vilket kan kortas ner till A+B>>C. INCI X ökar X med 1, vilket kan kortas ner till X++. SWAPI A B låter värdet av A hamna i B och värdet av B hamna i A, vilket kan kortas ner till A<>B. LETI X 18 J? testar huruvida X är mindre än 18, och lagrar i så fall 1 i J?, annars 0. Detta kan kortas ner till X<18>>J?. Motsvarigheten heter GRTI. GOTO J? Run anropar subrutinen Run (i detta fall rekursivt) om värdet av J? är 1.

Så här ser den korta versionen av mitt lilla Fibonacci-program ut:

1>>A <<A 1>>B <<B 0>>X
Run: A+B>>C <<C X++ A<>B B<>C X<18>>J?
GOTO J? Run
<<"Done!"

Apropå anrop så finns två nyckelord för att anropa subrutiner: GOTO och GOSB. Skillnaden mellan dessa är att GOTO egentligen bara ändrar nuvarande exekveringspunkt, medan GOSB (“go sub”) dessutom lagrar vilken plats man lämnar i en enkel callstack. Subrutiner som anropas med GOSB kan lämna tillbaka kontrollen till den anropande koden genom instruktionen RTRN (“return”) som plockar ett värde från callstacken. Om RTRN används när callstacken är tom avslutas programmet.

Trots att språket varken är färdigt eller släppt så finns redan konceptet som en Ruby DSL. Tack Jonas Elfström!

Jag återkommer med fler kodsnuttar, och tar tacksamt emot tips på namn! (Dawkins är upptaget eftersom eftersom den berömde biologen Richard Dawkins faktiskt också har designat ett programmeringsspråk.)

Uppdatering: Tidigare idag publicerade Roger Alsing en Fizz Buzz på Facebook. Finessen med hans Fizz Buzz var att den saknade tester, utan utnyttjade objektorienteringen i C# för att få till serien. Mitt språk är tyvärr inte objektorienterat, men så här ser en fungerande Fizz Buzz ut:

1>>I
Run:
   1>>C? I%3>>F F=0>>F? I%5>>B B=0>>B? F?&B?>>X?
   GOSB X? FizzBuzz
   GOSB B? Buzz
   GOSB F? Fizz
   GOSB C? NoFizzBuzz
   I++ I<101>>J?
   GOTO J? Run
/* Quit! */
RTRN

/* Sub routines... */
FizzBuzz: 0>>F? 0>>B? 0>>C? <<"Fizz Buzz" RTRN
Buzz: 0>>F? 0>>C? <<"Buzz" RTRN
Fizz: 0>>C? <<"Fizz" RTRN
NoFizzBuzz: <<I RTRN

Categories: Geeky

Tags: Gosbust

Leave a Reply

Your email address will not be published. Required fields are marked *



En kopp kaffe!

Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!

Bjud på en kopp kaffe!

Om...

Kontaktuppgifter, med mera, finns här.

Följ mig

Twitter Instagram
GitHub RSS

Public Service

Folkbildning om public service.

Hem   |   linktr.ee/hesselbom   |   winsoft.se   |   80tal.se   |   Filmtips