Ulimi olusha lwezinhlelo Mash

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.

В ВМ используется несколько стеков:

  1. Основной стек.
  2. Стек для хранения точек возврата.
  3. Стек сборщика мусора.
  4. 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.

iwebhusayithi
Indawo yokugcina ku-GitHub

Ngiyabonga ngokufunda kuze kube sekugcineni uma ufundile.

Source: www.habr.com

Engeza amazwana