Proceed High Language eli PHL on korkean tason yleiskäyttöinen proseduaalinen ohjelmointikieli, joka tukee myös olio-ohjelmointia.
Nykyinen versio: 1.2.6
Kotisivu: www.kaivos.org/doc/phl/phl.html
Kieli tukee mm.
&
, |
, yms ennen operaattoreita ==
, !=
, yms)Kielen kääntäjä on kirjoitettu Javalla ja kieli kääntyy assembly- tai C-tiedostoiksi. Olen kokeillut kääntäjää vain Linuxilla, mutta pienellä vaivalla sen todennäkoisesti saisi toimimaan myös Windowsissa.
Esimerkki- PHL-ohjelma:
module helloworld; extern printf; @Integer main [ printf("Hello World!\n"); return 0; ]
Parilliset:
var parilliset = (1..100).filter ( #(i) i % 2 == 0 ); printf("0"); parilliset each # (i) [ printf(",%i", i); ]; printf("\n");
Esimerkki olio-ohjelmoinnista:
module oliot; extern printf; /* Kopio C++:n ostream -luokasta */ class @Tulostaja { @Void tulosta(@String viesti) [ printf("%s\n", viesti); ] @Tulostaja operator <<(@String viesti) [ printf("%s", viesti); return this; ] @String endl [ return "\n"; ] }; @Integer main [ var viesti = "Päivää!"; var vastaus = "Samoin."; var tulostaja = new @Tulostaja; tulostaja.tulosta("Viesti: " + viesti); tulostaja << "Vastaus: " << vastaus << tulostaja::endl; return 0; ]
Olen työstänyt tätä kieltä vuodesta 2012 lähtien, en osaa sanoa kuinka paljon aikaa yhteensä on kulunut.
Tämä opas auttaa pääsemään alkuun PHL-ohjelmoinnissa. Lisäksi kannattaa lukea standardikirjaston ohjeet täältä.
Jos löydätte virheitä kääntäjästä tai kirjastoista, tai teillä on muuta kommentoitavaa, ilmoittakaa minulle.
Versio | Muutokset |
---|---|
Versio 1.2.7 TULOSSA PIAN |
|
Versio 1.2.6c |
|
Versio 1.2.6b | Korjauksia. |
Versio 1.2.6 | Uutta PHL-ohjelmointikieleen:
Johtuen standardikirjaston muutoksista kirjasto libphl ei ole enää oleellinen. Korjauksia. |
Versio 1.2.5 | PIL-tiedostojen kääntämistapa muuttunut! Sen sijaan, että kääntäjä tulostaisi ulostulon, täytyy ulostulo tiedosto määritellä erikseen Uutta PHL-ohjelmointikieleen:
Uutta PHL-kääntäjään:
Uutta PIL-kääntäjään:
Korjaukset: Paljon bugikorjauksia |
Versio 1.2.4 |
|
Versio 1.2.3b |
|
Versio 1.2.3 |
|
Versio 1.2.2b | Lisätty PHL-kääntäjään valitsimet --help, --path ja --out. |
Versio 1.2.2 |
|
Versio 1.2.1 | Tärkeitä korjauksia liittyen "template" -funktihin. |
Versio 1.2 | Ensimmäinen julkinen versio |
Olen luonut myös Sve-kielen, jonka Javascript-tulkkia voi kokeilla nettiselaimessa täällä. Svekielestä olen yrittänyt tehdä mahdollisimman dynaamisen ja elegantin, toisin kuin PHL-kielestä.
Saako kysyä (kettuilematta ja syyllistämättä), miksi? :)
Lebe80 kirjoitti:
Saako kysyä (kettuilematta ja syyllistämättä), miksi? :)
Harjoitukseksi tätä kai voi sanoa... Olin tehnyt Javascriptillä pienen ohjelmointikielen (linkki) ja mietin, voisiko siitä saada "kunnon" natiivikoodiksi kääntyvän C:n kaltaisen kielen.
Aloitin viime vuonna ja olen tehnyt tätä aina vähän kerrallaan muiden projektien välissä. Nyt minulla on tuhansia rivejä pitkä kääntäjä ja ajattelin laittaa sen tänne muiden arvosteltavaksi.
Kokeilin pikaisesti. Tuli ongelmia, vaikka sainkin Helloworldin toimimaan.
Ensinnäkin, käännösohjeessa on virheitä. Java-komennot pitää laittaa muodossa java -cp eikä java -jar, koska jar:in manifesti ei salli sen suorittamista.
Lopullisessa linkitysvaiheessa -lgc pitää olla viimeisenä gcc:n linkitysjärjestyssäännön takia. Muuten tulee virhe puuttuvasta symbolista. Olen Ubuntussa ja käytän gcc 4.7.3:a.
Seuraavaa ohjelmaa en saanut linkitettyä. Yritin kahdella eri tavalla, jotka kerron alla.
module helloworld2; extern printf; @Integer main [ var i = 0; while (i<10) { printf("Hello World!\n"); i = i + 1; } return 0; ]
Yritin ensin samalla tavalla kuin yksinkertaisen Helloworldin kanssa, jonka sain toimimaan. Virhe linkitysvaiheessa oli:
$ gcc -o helloworld2 helloworld2.o -lgc helloworld2.o: In function `function@main.L__label_function@main__while29_continue': helloworld2.asm:(.text+0x3f): undefined reference to `lib@lt' collect2: error: ld returned 1 exit status
No, ajattelin, että tuo lib@lt löytyy core-kirjastosta ja käänsin sen out-hakemistosta löytyvästä PIL-muodosta assemblyksi ja sitten nasmitin sen. Sain core.o-tiedoston, jonka yritin lisätä linkitysvaiheeseen:
$ gcc -o helloworld2 helloworld2.o core.o -lgc core.o: In function `function@nullPtrCheck': core.asm:(.text+0x171): undefined reference to `err_println' collect2: error: ld returned 1 exit status
En tiedä mikä on err_println, joten annoin periksi tässä vaiheessa.
Koko komentosarjani on siis seuraava, kun saan jälkimmäisen virheen. Jos jätän core-kirjaston käsittelyn pois, saan ensimmäisen virheen.
$ java -cp phl.jar org.kaivos.proceedhl.parser.ProceedParser hello2.phl $ java -cp phl.jar org.kaivos.proceed.parser.ProceedParser out/helloworld2.pil > helloworld2.asm $ java -cp phl.jar org.kaivos.proceed.parser.ProceedParser out/phl_lang_core.pil > core.asm $ nasm -f elf -o helloworld2.o helloworld2.asm $ nasm -f elf -o core.o core.asm $ gcc -o helloworld2 helloworld2.o core.o -lgc
Kiitos kun ilmoitit virheistä ohjeessa. Korjaan ne pikimmiten.
err_println on funktio, joka tulostaa virheviestin virheulostuloon. Se löytyy kirjastosta libphl.so, jonka olin tehnyt kauan sitten ja jättänyt /usr/lib -kansioon. Olen pahoillani huolimattomuudestani.
Tässä on C-koodi kyseiselle funktiolle:
#include <stdio.h> void err_println(char* msg) { fprintf(stderr, msg); }
Laitoin kirjaston myös nettisivulleni.
Core-kirjasto sisältää @Integer-rajapinnan kaikki jäsenfunktiot, myös "less than" -funktion lib@lt. Kääntäjä olettaa, että core-kirjasto linkitetään aina.
Minulla voi olla vielä lisää palautetta, kunhan kerkeän kokeilemaan erinäisiä asioita perusteellisemmin. Joka tapauksessa sain silmukkakokeiluni nyt linkattua, ja se toimi kuten pitikin.
Kirjaston libphl.so käyttö vaatii vielä, että se on hakemistossa, josta järjestelmä löytää sen linkatakseen sen dynaamisesti. Se kannattaa siis laittaa joko /usr/local/lib -hakemistoon tai vastaavaan paikkaan, tai sitten asettaa LD_LIBRARY_PATH -ympäristömuuttuja sisältämään oikea hakemisto. Muuten ohjelmaa suoritettaessa tulee virheilmoitus, ettei libphl.so:ta löydy. Tästä kai voisi ohjeessa myös mainita.
Heipä taas. Kokeilin hieman ajatuksena tehdä etukäteen mietittyjä testejä kielen toiminnasta, mutta nyt vaivaa virheellinen assembly ja o-tiedoston tekeminen ei onnistu.
Käytän uusimpia versioita sivultasi ladattavista tiedostoista. Nasm on Ubuntun repoista löytyvä versio: NASM version 2.10.01 compiled on Jun 14 2012
Kun yritän kääntää phl_core-kirjastoa, käännösvaihe PIL-koodista assemblyksi tuottaa tuloksen, joka ei kelpaa Nasmille. Se käy näin:
pekka@kuutio:~/Downloads/phl$ java -cp phl.jar org.kaivos.proceedhl.parser.ProceedParser lib/phl/lang/core.phl pekka@kuutio:~/Downloads/phl$ ls out phl_lang_core.pil pekka@kuutio:~/Downloads/phl$ java -cp phl.jar org.kaivos.proceed.parser.ProceedParser out/phl_lang_core.pil > out/phl_lang_core.asm pekka@kuutio:~/Downloads/phl$ ls out phl_lang_core.asm phl_lang_core.pil pekka@kuutio:~/Downloads/phl$ nasm -f elf -o out/phl_lang_core.o out/phl_lang_core.asm out/phl_lang_core.asm:1261: error: invalid combination of opcode and operands out/phl_lang_core.asm:1505: error: invalid combination of opcode and operands out/phl_lang_core.asm:6841: error: invalid combination of opcode and operands
Lisäksi Shell-skriptissä on ongelma hakemistojen käsittelyssä. Se löytää out-hakemistosta tiedostoja, joiden nimessä on mukana polku niihin, mutta lisää kuitenkin out-hakemiston niiden eteen käyttäessään niitä. Tuloksena on tiedostoviittauksia, jotka alkavat out/out/ ja tässä on yksi out liikaa. Mahdollisesti näiden ylimääräisten out/-alkujen poisto komennoista paikkaa asian toistaiseksi.
Pienempi ongelma on se, että alun rm-komento tuottaa virheitä, jos yhtään halutun kaltaista tiedostoa ei löydy out-hakemistosta poistettavaksi. Se ei nyt juuri minua haittaa.
En taaskaan uskalla luvata, milloinka on seuraava kertani kielen parissa. Aion kuitenkin taas kokeilla asioita joskus lisää. Ei ole siis kiire minun puolestani selventää asioita, koska palaan taas asiaan myöhemmin. Pidän nyt nuo tiedostot hetken tallessa koneellani, jos haluat ne vaikkapa nähdä, mutta käsittääkseni sinun pitäisi saada juuri sama asm-tiedosto tehtyä omalla koneellasikin.
Kuitenkin yksi toive olisi ensi kerraksi. Tee asennusskripti, joka tekee halutut hakemiston nykyisen alle ja hakee sinne wgetillä tarvittavat tiedostot kotisivultasi. Sen jälkeen kääntäjän voi asentaa helposti lataamalla vain tämä skripti ja ajamalla se sopivassa hakemistossa.
Kiitos, kun ilmoitit virheestä kääntäjässä.
Näyttää siltä, että phl.jar:in sisällä on vanhentunut versio PIL-kääntäjästä, joka ei ymmärrä uuden PHL-kääntäjän tulostamaa koodia. Testasin kääntäjää ennen sen pakkaamista jariksi ja en siksi huomannut laittaneeni vahingossa vääriä tiedostoja jarin sisään.
Olen nyt lomalla joten en voi päivittää tiedostoja kotisivullani, mutta palaan muutaman päivän päästä ja lataan uuden version kotisivulleni.
Asennusskripti on hyvä idea, aion tehdä sellaisen, kun on aikaa. Kiitos ideasta ja muusta palautteesta.
Lisäys: Ongelma korjattu PHL:n uusimmassa versiossa 1.2.5.
Luin kommenttisi toisesta ketjusta. Olin hieman pettynyt siihen, mutta enimmäkseen huvittunut.
fergusq kirjoitti:
Forth ei minusta sovi ensimmäiseksi kieleksi. Sen syntaksi on jo niin erikoinen verrattuna yleisempiin kieliin, että vaikka sen oppisi ei saisi mitään hyödyllistä "tuntumaa" muihin Forthia tärkeämpiin kieliin, joita ohjelmoijan on hyvä osata.
Tällä kommentilla oli nyt sellainen vaikutus, että se vei viimeisenkin ripauksen mielenkiinnostani PHL:ää kohtaan. Kääntäjän toimimattomuus viime kerralla vei jo osan, eikä kielessä alkujaankaan mikään ominaisuus varsinaisesti näyttänyt minulle uudelta ja kiinnostavalta. Lisäksi en löytänyt mistään esimerkiksi kaikkien operaattoreiden tarkkoja määrittelyjä, mutta ehkä se johtui siitä, että en kerennyt hakea. Se ei ole ongelma enää.
Toivotan kielellesi sen ansaitsemaa menestystä. Oma kiinnostukseni tähän projektiin loppui toistaiseksi kokonaan.
(Mod. siirsi viestin osittain asianmukaiseen keskusteluun.)
Jos ketään enää kiinnostaa, vastaukseni on lievästi sanottuna hieman myöhässä.
Pekka Karjalainen kirjoitti:
Lisäksi en löytänyt mistään esimerkiksi kaikkien operaattoreiden tarkkoja määrittelyjä [...]
Olisitpa, Pekka Karjalainen, esittänyt tämän ennen kuin tajusit, mitä mieltä minä olen ohjelmoinnin aloittamisesta Forthilla. Olisi silloin ollut enemmän puhtia vastatakin jotain.
Tämä seuraava on kaikille niille harvoille, jotka vielä joskus tutkivat tätä minun 14-vuotiaana koodaamaani sekavasti toteutettua ohjelmointikieltä. Minä en kielen luotuani juurikaan jaksanut sen suunnittelua dokumentoida.
Operaattorien tarkkoja määrittelyjä ei ole olemassa, koska niitä ei ole ollenkaan määritelty. Selitänpä nyt, mitä se tarkoittaa.
Ensinnäkin, kieli on jaettu kahteen tärkeään osaan. Kääntäjään, joka määrittää kielen syntaksin ja semantiikat, sekä standardikirjastoon, joka sisältää rajapintoja, luokkia ja funktioita keskeisten asioiden hoitamiseen.
Kieltä suunnitellessani pyrin helpottamaan asioiden kokeilemista ja kielen laajentamista, joten siirsin lähes kaiken toiminnallisuuden standardikirjastolle. Toisin sanoen kääntäjä tulkitsi ainoastaan literaalit ja metodien (joita operaattorit ovat) toteutus jäi kirjastolle.
Binäärioperaattoreita, +
, -
, jne, joita Karjalainen luultavasti tarkoitti, ei ole määritelty kielessä itsessään, vaan jokainen stdkirjaston tyyppirajapinta määrittelee ne itsenäisesti. Esimerkiksi @Integer
-rajapinnan metodi operator +
on määritelty core.phl-tiedostossa, joka on saatavilla github-sivuiltani.
Ko. tiedosto määrittelee ko. operaattorin seuraavasti:
@Integer add(@Integer i) alias +; @Integer operator+(@Integer i) alias @Integer.add;
Eli siis operator +
on alias metodille add
, joka on alias funktiolle +
.
Tässä kohtaa on syytä huomauttaa, että minun PHL-toteutukseni sallii funktion nimen olla +
. Tämä on vastoin määritystä ja olen välillä miettinyt asian muuttamista.
+
on sattumoisin PIL-kielen määrityksessä listattu sisäänrakennettu funktio (pseudofunktio). +
:aa ei ole tarkkaan määritelty, sillä sen toteutus on alustariippuvainen ja vaihtelee kohdekielestä riippuen (C, x86, amd64). Sen on kuitenkin taattu suorittavan jonkin kaltaisen yhteenlaskun kahden luvun välillä (kokonaisluku on ainoa PIL:n tietotyyppi). Uskoakseni kaikki tietävät, mitä yhteenlasku tarkoittaa.
Kaikki operaattorit on määritelty stdkirjastossa ja kaikkien pseudofunktioiden määritykset löytää sivustoni PIL-osiosta. Dokumentaatio on epäselvää, myönnän. Jos tieto olisi arvokkaampaa, sitä olisi enemmän.
Kuten huomataan, PHL on vahvasti alustariippuvainen kieli. Tämä johtuu siitä, että kieltä suunnitellessani ajattelin täyden alustariippumattomuuden olevan mahdoton tavoite. Lisäksi pyrin tällä estämään turhaa kikkailua, esimerkiksi bittioperaatiot ovat liian usein vain sekavaa mössöä, jonka voisi toteuttaa ilmankin selkeästi. PHL:n stdkirjasto tukee joitain bittioperaatioita, valitettavasti, mutta vain, koska se niitä sisäisesti käyttää.
PHL:n laajennettavuus on, hienoisen sekavuuden kustannuksella, etu. PHL:n voi saada standardikirjastoa muuntelemalla aivan uudenlaiseksi. PHL on näin ollen melko sopeutuva.
Semmonen vain että tuota roskien kerääjää ei enään löydy tuolta readmessa mainitusta linkistä.
Niinpä näkyy. Pikaisella selaamisella uusi osoite näyttäisi olevan http://www.hboehm.info/gc/.
Päivitän kotisivulleni kun ehdin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.