Bag-ong programming language nga Mash

Sulod sa daghang mga tuig gisulayan nako ang akong kamot sa paghimo sa akong kaugalingon nga programming language. Gusto nako nga maghimo, sa akong opinyon, ang labing yano, hingpit nga magamit ug kombenyente nga pinulongan nga posible.

Niini nga artikulo gusto nakong ipasiugda ang mga nag-unang yugto sa akong trabaho ug, sa pagsugod, ihulagway ang namugna nga konsepto sa pinulongan ug ang unang pagpatuman niini, nga akong gitrabaho karon.

Isulti ko daan nga gisulat nako ang tibuuk nga proyekto sa Libre nga Pascal, tungod kay... Ang mga programa niini mahimong tipunon alang sa usa ka dako nga gidaghanon sa mga plataporma, ug ang compiler mismo nagpatunghag maayo kaayo nga mga binary (akong gikolekta ang tanan nga mga sangkap sa proyekto nga adunay O2 nga bandila).

Runtime sa pinulongan

Una sa tanan, angay nga hisgutan ang virtual nga makina nga kinahanglan nakong isulat aron mapadagan ang umaabot nga mga aplikasyon sa akong sinultian. Nakahukom ko nga ipatuman ang usa ka arkitektura sa stack, tingali, tungod kay kini ang labing kadali nga paagi. Wala akoy nakit-an nga bisan usa ka normal nga artikulo kung giunsa kini buhaton sa Russian, busa pagkahuman napamilyar ang akong kaugalingon sa materyal nga English-pinulongan, milingkod ako sa pagdesinyo ug pagsulat sa akong kaugalingon nga bisikleta. Sunod akong ipresentar ang akong "advanced" nga mga ideya ug mga kalamboan niini nga butang.

Implementasyon sa stack

Dayag, sa ibabaw sa VM mao ang stack. Sa akong pagpatuman kini nagtrabaho sa mga bloke. Sa tinuud kini usa ka yano nga han-ay sa mga pointer ug usa ka variable aron tipigan ang indeks sa ibabaw sa stack.
Kung kini gisugdan, usa ka han-ay sa 256 nga mga elemento ang gihimo. Kung daghang mga pointer ang iduso sa stack, ang gidak-on niini madugangan sa sunod nga 256 nga mga elemento. Tungod niini, kung gikuha ang mga elemento gikan sa stack, ang gidak-on niini gi-adjust.

Ang VM naggamit sa daghang mga stack:

  1. Panguna nga stack.
  2. Usa ka stack alang sa pagtipig sa mga punto sa pagbalik.
  3. Tigkolekta sa basura.
  4. Sulayi / dakpon / sa katapusan babagan ang stack sa handler.

Mga Constant ug Variable

Kini usa ka yano. Ang mga Constant gidumala sa usa ka bulag nga gamay nga piraso sa code ug magamit sa umaabot nga mga aplikasyon pinaagi sa mga static nga adres. Ang mga variable usa ka han-ay sa mga pointer sa usa ka piho nga gidak-on, ang pag-access sa mga selyula niini gihimo pinaagi sa indeks - i.e. static nga adres. Ang mga variable mahimong itulod sa ibabaw sa stack o basahon gikan didto. Sa pagkatinuod, tungod kay Samtang ang among mga variable hinungdanon nga nagtipig mga pointer sa mga kantidad sa panumduman sa VM, ang lengguwahe gidominar pinaagi sa pagtrabaho kauban ang mga implicit nga mga punto.

Tigkolekta sa basura

Sa akong VM kini semi-awtomatiko. Mga. ang developer mismo ang modesisyon kung kanus-a tawgon ang tigkolekta sa basura. Dili kini molihok gamit ang usa ka regular nga pointer counter, sama sa Python, Perl, Ruby, Lua, ug uban pa. Gipatuman kini pinaagi sa usa ka marker system. Mga. kung ang usa ka variable gituyo nga hatagan usa ka temporaryo nga kantidad, usa ka pointer sa kini nga kantidad idugang sa stack sa tigkolekta sa basura. Sa umaabot, ang kolektor dali nga modagan sa naandam na nga listahan sa mga punto.

Pagdumala sa pagsulay/pagdakop/sa katapusan block

Sama sa bisan unsang modernong pinulongan, ang pagdumala sa eksepsiyon usa ka importante nga bahin. Ang VM core giputos sa usa ka try..catch block, nga makabalik sa code execution human makuha ang usa ka eksepsiyon pinaagi sa pagduso sa pipila ka impormasyon mahitungod niini ngadto sa stack. Sa code sa aplikasyon, mahimo nimong ipasabut ang pagsulay / pagdakop / katapusan nga mga bloke sa code, pagtino sa mga punto sa pagsulod sa catch (exception handler) ug katapusan / katapusan (katapusan sa block).

Multithreading

Gisuportahan kini sa lebel sa VM. Kini yano ug sayon ​​nga gamiton. Naglihok kini nga wala’y interrupt system, busa ang code kinahanglan nga ipatuman sa daghang mga hilo sa daghang beses nga mas paspas, matag usa.

Mga eksternal nga librarya para sa mga VM

Wala’y paagi nga mahimo kung wala kini. Gisuportahan sa VM ang mga import, susama sa kung giunsa kini gipatuman sa ubang mga sinultihan. Mahimo nimong isulat ang bahin sa code sa Mash ug bahin sa code sa lumad nga mga pinulongan, dayon i-link kini sa usa.

Maghuhubad gikan sa taas nga lebel sa pinulongang Mash hangtod sa bytecode alang sa mga VM

Intermediate nga pinulongan

Aron dali nga makasulat sa usa ka tighubad gikan sa usa ka komplikado nga pinulongan ngadto sa VM code, una nakong gihimo ang usa ka intermediate nga pinulongan. Ang resulta mao ang usa ka assembler-sama sa makalilisang nga talan-awon nga walay partikular nga punto sa pagkonsiderar dinhi. Isulti ra nako nga sa kini nga lebel ang tighubad nagproseso sa kadaghanan nga mga kanunay ug mga variable, gikalkula ang ilang mga static nga adres ug ang mga adres sa mga punto sa pagsulod.

Arkitektura sa tighubad

Wala ko gipili ang labing kaayo nga arkitektura alang sa pagpatuman. Ang maghuhubad wala maghimo ug code tree, sama sa gibuhat sa ubang mga maghuhubad. Gitan-aw niya ang sinugdanan sa istruktura. Mga. kung ang piraso sa code nga gi-parse morag "samtang <kondisyon>:", nan klaro nga kini usa ka while loop construct ug kinahanglan nga iproseso isip usa ka while loop construct. Usa ka butang sama sa usa ka komplikado nga switch-case.

Salamat sa kini nga solusyon sa arkitektura, ang tighubad nahimo nga dili kaayo paspas. Bisan pa, ang kasayon ​​sa pagbag-o niini miuswag pag-ayo. Gidugang nako ang gikinahanglan nga mga istruktura nga mas paspas kay sa mabugnaw sa akong kape. Ang bug-os nga suporta sa OOP gipatuman sa wala pay usa ka semana.

Pag-optimize sa code

Dinhi, siyempre, mahimo unta kini nga ipatuman nga mas maayo (ug ipatuman, apan sa ulahi, sa diha nga ang usa makalibut niini). Sa pagkakaron, nahibal-an ra sa optimizer kung giunsa ang pagputol sa wala magamit nga code, kanunay ug pag-import gikan sa asembliya. Usab, daghang mga kanunay nga adunay parehas nga kantidad ang gipulihan sa usa. Mao ra.

Mash sa Pinulongan

Batakang konsepto sa pinulongan

Ang nag-unang ideya mao ang pagpalambo sa labing praktikal ug yano nga pinulongan nga posible. Sa akong hunahuna nga ang pag-uswag nakasagubang sa tahas niini sa usa ka bang.

Mga bloke sa code, mga pamaagi ug mga gimbuhaton

Ang tanan nga mga konstruksyon sa pinulongan giablihan sa usa ka colon. : ug gisirhan sa operator katapusan.

Ang mga pamaagi ug mga gimbuhaton gideklarar nga proc ug func, matag usa. Ang mga argumento gilista sa parentesis. Ang tanan sama sa kadaghanan sa ubang mga pinulongan.

Operator pagbalik mahimo nimong ibalik ang usa ka kantidad gikan sa usa ka function, operator pahugno nagtugot kanimo sa paggawas sa pamaagi / function (kung kini sa gawas sa mga galong).

Sample code:

...

func summ(a, b):
  return a + b
end

proc main():
  println(summ(inputln(), inputln()))
end

Gisuportahan nga mga Disenyo

  • Loops: kay..katapusan, samtang..katapusan, hangtod..katapusan
  • Kondisyon: kung..[lain..]tapos, switch..[kaso..katapusan..][lain..]tapos
  • Pamaagi: proc <name>():... end, func <name>():... end
  • Label & goto: <ngalan>:, ambak <ngalan>
  • Enum enumerations ug kanunay nga arrays.

Mga variable

Ang tighubad makahimo sa pagtino niini nga awtomatiko, o kung ang developer nagsulat var sa dili pa kini ipasabut.

Mga pananglitan sa code:

a ?= 10
b ?= a + 20

var a = 10, b = a + 20

Gisuportahan ang global ug lokal nga mga variable.

OOP

Aw, nakaabot na kami sa labing lamian nga hilisgutan. Gisuportahan sa Mash ang tanan nga mga paradigma sa pagprograma sa object-oriented. Mga. mga klase, kabilin, polymorphism (lakip ang dinamiko), dinamikong awtomatik nga pagpamalandong ug introspection (puno).

Kung wala’y dugang nga ado, mas maayo nga maghatag lang mga pananglitan sa code.

Usa ka yano nga klase ug nagtrabaho uban niini:

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

Ang output: 30.

Kabilin ug polymorphism:

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

Ang output: 60.

Unsa man ang bahin sa dinamikong polymorphism? Oo, kini ang pagpamalandong!:

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

Ang output: 60.

Karon maggahin kita og kadiyot sa pagsusi alang sa yano nga mga mithi ug mga klase:

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

Ang output: tinuod, tinuod.

Mahitungod sa mga operator sa assignment ug klaro nga mga punto

Ang ?= operator gigamit sa pag-assign sa variable ug pointer sa usa ka value sa memory.
Ang = operator nag-usab sa usa ka bili sa memorya gamit ang usa ka pointer gikan sa usa ka variable.
Ug karon usa ka gamay bahin sa tin-aw nga mga punto. Gidugang ko sila sa pinulongan aron sila anaa.
@<variable> β€” pagkuha ug klaro nga pointer sa usa ka variable.
?<variable> β€” pagkuha ug variable pinaagi sa pointer.
@= β€” paghatag ug bili sa usa ka variable pinaagi sa usa ka tin-aw nga pointer niini.

Sample code:

uses <bf>
uses <crt>

proc main():
  var a = 10, b
  b ?= @a
  PrintLn(b)
  b ?= ?b
  PrintLn(b)
  b++
  PrintLn(a)
  InputLn()
end

Ang output: pipila ka numero, 10, 11.

Sulayi..[dakup..][katapusan..]katapusan

Sample code:

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

Mga plano alang sa umaabot

Nagsige kog tan-aw ug tan-aw sa GraalVM & Truffle. Ang akong runtime nga palibot walay JIT compiler, mao nga sa mga termino sa pasundayag kini sa pagkakaron nakigkompetensya lamang sa Python. Nanghinaut ko nga ako makahimo sa pagpatuman sa JIT compilation base sa GraalVM o LLVM.

tipiganan

Mahimo nimong dulaon ang mga kalamboan ug sundon ang proyekto sa imong kaugalingon.

Π‘Π°ΠΉΡ‚
Repository sa GitHub

Salamat sa pagbasa hangtod sa katapusan kung nabasa nimo.

Source: www.habr.com

Idugang sa usa ka comment