Iminyaka eminingana ngizama isandla sami ekuthuthukiseni ulimi lwami lokuhlela. Bengifuna ukwakha, ngokombono wami, ulimi olulula kakhulu, olusebenza ngokugcwele nolulula ngangokunokwenzeka.
Kulesi sihloko ngifuna ukugqamisa izigaba eziyinhloko zomsebenzi wami futhi, okokuqala, ngichaze umqondo owenziwe wolimi kanye nokuqaliswa kwawo kokuqala, engisebenza kuwo njengamanje.
Ake ngisho kusenesikhathi ukuthi ngibhale yonke iphrojekthi ku-Free Pascal, ngoba... izinhlelo ezikuyo zingaqoqelwa inani elikhulu lamapulatifomu, futhi umhlanganisi ngokwawo ukhiqiza amabhinari alungiselelwe kakhulu (ngiqoqa zonke izingxenye zephrojekthi ngefulegi le-O2).
Isikhathi sokusebenza solimi
Okokuqala, kufanelekile ukukhuluma ngomshini obonakalayo obekufanele ngiwubhale ukuze ngisebenzise izinhlelo zokusebenza ezizayo ngolimi lwami. Nginqume ukusebenzisa ukwakheka kwesitaki, mhlawumbe, ngoba bekuyindlela elula. Angizange ngithole nesisodwa isihloko esivamile sendlela yokwenza lokhu ngesiRashiya, ngakho ngemva kokuzijwayeza ukwaziswa kolimi lwesiNgisi, ngahlala phansi ngaklama nokubhala ibhayisikili lami. Okulandelayo ngizokwethula imibono yami “ethuthukisiwe” kanye nentuthuko kulolu daba.
Ukuqaliswa kwesitaki
Ngokusobala, phezulu kwe-VM kukhona isitaki. Ekusetshenzisweni kwami kusebenza kumabhulokhi. Empeleni lolu uhlu olulula lwezikhombi kanye nokuguquguqukayo kokugcina inkomba yangaphezulu kwesitaki.
Uma iqaliswa, uhlu lwama-elementi angu-256 luyakhiwa. Uma izikhombi ezengeziwe ziphushwa esitakini, usayizi waso ukhuphuka ngama-elementi angu-256 alandelayo. Ngokuvumelana nalokho, lapho ukhipha izakhi esitaki, usayizi waso uyalungiswa.
В ВМ используется несколько стеков:
- Основной стек.
- Стек для хранения точек возврата.
- Стек сборщика мусора.
- Zama/bamba/ekugcineni uvimbele isitaki sesibambi.
Константы и переменные
С этим все просто. Константы обрабатываются отдельным небольшим куском кода и доступны в приложениях в будущем по статическим адресам. Переменные представляют собой массив указателей определенного размера, доступ к его ячейкам осуществляется по индексу — т.е. статическому адресу. Переменные можно помещать в вершину стека или читать её оттуда. Собственно, т.к. у нас переменные по сути хранят указатели на значения в памяти ВМ, то в языке преобладает работа с неявными указателями.
Umqoqi wezibi
В моей ВМ он полуавтоматический. Т.е. разработчик сам решает когда нужно вызвать сборщик мусора. Работает он не по обычному счетчику указателей, как в тех же Python, Perl, Ruby, Lua и т.д. Он реализован через систему маркеров. Т.е. когда подразумевается, что переменной присваивается временное значение — указатель на это значение добавляется в стек сборщика мусора. В дальнейшем сборщик быстро пробегается по уже готовому списку указателей.
Ukuphatha zama/ukubamba/ekugcineni kuyavimba
Njengakunoma yiluphi ulimi lwesimanje, ukuphatha okuhlukile kuyingxenye ebalulekile. I-VM core isongwe nge-try..catch block, engabuyela ekwenziweni kwekhodi ngemva kokubamba okuhlukile ngokucindezela ulwazi oluthile ngakho esitakini. Ekhodini yesicelo, ungachaza ukuzama/ukubamba/ekugcineni amabhlogo ekhodi, ucacise amaphuzu okungena ekubambeni (isibambi esihlukile) futhi ekugcineni/ekupheleni (ekupheleni kwebhulokhi).
Multithreading
Isekelwa ezingeni le-VM. Kulula futhi kulula ukuyisebenzisa. Isebenza ngaphandle kwesistimu yokuphazamiseka, ngakho-ke ikhodi kufanele ifakwe emicu eminingi ngokushesha izikhathi ezimbalwa, ngokulandelanayo.
Imitapo yolwazi yangaphandle yama-VM
Без этого никак не обойтись. ВМ поддерживает импорты, подобно тому, как это реализовано и в других языках. Можно написать часть кода на Mash и часть кода на нативных языках, затем связав их в одно целое.
Umhumushi osuka kulimi lwe-Mash olusezingeni eliphezulu ukuya kwi-bytecode yama-VM
Ulimi oluphakathi
Для быстрого написания транслятора со сложного языка в код для ВМ я сначала разработал промежуточный язык. Получилось ассемблероподобное страшное зрелище, которое рассматривать здесь нету особого смысла. Скажу лишь то, что на этом уровне транслятор обрабатывает большинство констант, переменных, вычисляет их статические адреса и адреса точек входа.
Архитектура транслятора
Angikhethanga i-architecture engcono kakhulu ezosetshenziswa. Umhumushi akasakhi isihlahla sekhodi, njengoba kwenza abanye abahumushi. Ubheka ekuqaleni kwesakhiwo. Labo. uma ucezu lwekhodi olucutshungulwayo lubukeka njengokuthi "ngenkathi <condition>:", khona-ke kusobala ukuthi lokhu ukwakhiwa kwe-loop yesikhashana futhi kudinga ukucutshungulwa njengokwakhiwa kwe-loop yesikhashana. Okuthile okufana nekesi lokushintsha eliyinkimbinkimbi.
Ngenxa yalesi sixazululo sezakhiwo, umhumushi akasheshi kakhulu. Nokho, ukukhululeka kokuguqulwa kwayo kuye kwanda kakhulu. Ngengeza izakhiwo ezidingekayo ngokushesha kunokuba ikhofi lami lingapholisa. Usekelo olugcwele lwe-OOP lwenziwe esikhathini esingaphansi kweviki.
Ukuthuthukisa ikhodi
Lapha, vele, ibingase isetshenziswe kangcono (futhi izosetshenziswa, kodwa kamuva, ngokushesha nje lapho umuntu efika kuyo). Kuze kube manje, i-optimizer yazi kuphela ukuthi ungayinqamula kanjani ikhodi engasetshenziswanga, ama-constants kanye nokungeniswa ngaphandle kwenhlangano. Futhi, ama-constants amaningana anenani elifanayo athathelwa indawo eyodwa. Yilokho kuphela.
Ulimi lwe-Mash
Основная концепция языка
Umqondo oyinhloko kwakuwukusungula ulimi olusebenziseka kalula nolulula ngangokunokwenzeka. Ngicabanga ukuthi intuthuko ibhekana nomsebenzi wayo nge-bang.
Amabhulokhi ekhodi, izinqubo kanye nemisebenzi
Zonke izakhiwo ngolimi zivulwa ngekholoni. : futhi zivalwa opharetha ekupheleni.
Izinqubo nemisebenzi imenyezelwa njenge-proc ne-func, ngokulandelana. Izimpikiswano zifakwe kubakaki. Konke kufana nezinye izilimi eziningi.
Opharetha ukubuya ungabuyisela inani kusuka kumsebenzi, opharetha ukuphuka позволяет выйти из процедуры/функции (если он стоит вне циклов).
Ikhodi yesampula:
...
func summ(a, b):
return a + b
end
proc main():
println(summ(inputln(), inputln()))
end
Imiklamo Esekelwe
- Izihibe: oko..kuphela, ngenkathi..kuphela, kuze..kuphele
- Условия: if..[else..]end, switch..[case..end..][else..]end
- Izindlela: proc <name>():... end, func <name>():... end
- Ilebula & goto: <name>:, gxuma <name>
- Enum перечисления и константные массивы.
Okuguquguqukayo
Umhumushi angazinquma ngokuzenzakalelayo, noma uma unjiniyela ebhala i-var ngaphambi kokuzichaza.
Izibonelo zekhodi:
a ?= 10
b ?= a + 20
var a = 10, b = a + 20
Okuguquguqukayo komhlaba kanye nendawo kuyasekelwa.
OOP
Hhayi-ke, sifike esihlokweni esimnandi kakhulu. I-Mash isekela wonke ama-paradigm ezinhlelo agxile entweni. Labo. amakilasi, ifa, i-polymorphism (kufaka phakathi okuguquguqukayo), ukubonisa okuzenzakalelayo okuguquguqukayo kanye nokuzihlola (okugcwele).
Ngaphandle kokuchitha isikhathi, kungcono ukunikeza izibonelo zekhodi.
Ikilasi elilula nokusebenza nalo:
uses <bf>
uses <crt>
class MyClass:
var a, b
proc Create, Free
func Summ
end
proc MyClass::Create(a, b):
$a = new(a)
$b = new(b)
end
proc MyClass::Free():
Free($a, $b)
$rem()
end
func MyClass::Summ():
return $a + $b
end
proc main():
x ?= new MyClass(10, 20)
println(x->Summ())
x->Free()
end
Выведет: 30.
Наследование и полиморфизм:
uses <bf>
uses <crt>
class MyClass:
var a, b
proc Create, Free
func Summ
end
proc MyClass::Create(a, b):
$a = new(a)
$b = new(b)
end
proc MyClass::Free():
Free($a, $b)
$rem()
end
func MyClass::Summ():
return $a + $b
end
class MyNewClass(MyClass):
func Summ
end
func MyNewClass::Summ():
return ($a + $b) * 2
end
proc main():
x ?= new MyNewClass(10, 20)
println(x->Summ())
x->Free()
end
Выведет: 60.
Что на счет динамического полиморфизма? Да это же рефлексия!:
uses <bf>
uses <crt>
class MyClass:
var a, b
proc Create, Free
func Summ
end
proc MyClass::Create(a, b):
$a = new(a)
$b = new(b)
end
proc MyClass::Free():
Free($a, $b)
$rem()
end
func MyClass::Summ():
return $a + $b
end
class MyNewClass(MyClass):
func Summ
end
func MyNewClass::Summ():
return ($a + $b) * 2
end
proc main():
x ?= new MyClass(10, 20)
x->Summ ?= MyNewClass::Summ
println(x->Summ())
x->Free()
end
Выведет: 60.
Manje ake sithathe isikhashana sihlole amanani alula namakilasi:
uses <bf>
uses <crt>
class MyClass:
var a, b
end
proc main():
x ?= new MyClass
println(BoolToStr(x->type == MyClass))
x->rem()
println(BoolToStr(typeof(3.14) == typeReal))
end
Выведет: true, true.
Mayelana nabaqhubi bezabelo kanye nezinkomba ezicacile
I-?= opharetha isetshenziselwa ukwabela okuguquguqukayo kwesikhombi kunani elisenkumbulweni.
U-opharetha = ushintsha inani lememori esebenzisa isikhombisi esivela kokuguquguqukayo.
Futhi manje kancane mayelana nezikhombisi ezicacile. Ngiwafake olimini ukuze abe khona.
@<variable> — thatha isikhombi esicacile uye kokuguquguqukayo.
?<variable> — thola i-variable by pointer.
@= — yabela inani kokuguquguqukayo ngesikhombi esicacile kukho.
Ikhodi yesampula:
uses <bf>
uses <crt>
proc main():
var a = 10, b
b ?= @a
PrintLn(b)
b ?= ?b
PrintLn(b)
b++
PrintLn(a)
InputLn()
end
Okukhiphayo: inombolo ethile, 10, 11.
Zama..[catch..][ekugcineni..]phela
Ikhodi yesampula:
uses <bf>
uses <crt>
proc main():
println("Start")
try:
println("Trying to do something...")
a ?= 10 / 0
catch:
println(getError())
finally:
println("Finally")
end
println("End")
inputln()
end
Izinhlelo zekusasa
Все присматриваюсь да присматриваюсь к GraalVM & Truffle. У моей среды выполнения отсутствует JIT компилятор, так что в плане производительности он пока что может составлять конкуренцию разве что питону. Надеюсь, что мне окажется под силу реализовать JIT компиляцию на базе GraalVM или LLVM.
inqolobane
Ungadlala ngentuthuko futhi ulandele iphrojekthi ngokwakho.
Ngiyabonga ngokufunda kuze kube sekugcineni uma ufundile.
Source: www.habr.com