Stwnsh iaith raglennu newydd

Am nifer o flynyddoedd bûm yn ceisio datblygu fy iaith raglennu fy hun. Roeddwn i eisiau creu, yn fy marn i, yr iaith fwyaf syml, gwbl weithredol a chyfleus posib.

Yn yr erthygl hon rwyf am dynnu sylw at brif gamau fy ngwaith ac, i ddechrau, disgrifio’r cysyniad a grëwyd o’r iaith a’i gweithrediad cyntaf, yr wyf yn gweithio arno ar hyn o bryd.

Gadewch imi ddweud ymlaen llaw imi ysgrifennu'r prosiect cyfan yn Free Pascal, oherwydd ... gellir cydosod rhaglenni arno ar gyfer nifer fawr o lwyfannau, ac mae'r casglwr ei hun yn cynhyrchu deuaidd optimaidd iawn (rwy'n casglu holl gydrannau'r prosiect gyda baner O2).

Amser rhedeg iaith

Yn gyntaf oll, mae'n werth siarad am y peiriant rhithwir y bu'n rhaid i mi ei ysgrifennu i redeg cymwysiadau yn fy iaith yn y dyfodol. Penderfynais weithredu pensaernïaeth stac, efallai, oherwydd dyna oedd y ffordd hawsaf. Wnes i ddim dod o hyd i un erthygl arferol ar sut i wneud hyn yn Rwsieg, felly ar ôl ymgyfarwyddo â’r deunydd Saesneg, eisteddais i lawr i ddylunio ac ysgrifennu fy meic fy hun. Nesaf byddaf yn cyflwyno fy syniadau “uwch” a datblygiadau yn y mater hwn.

Gweithredu stac

Yn amlwg, ar frig y VM mae'r pentwr. Yn fy ngweithrediad mae'n gweithio mewn blociau. Yn ei hanfod mae hwn yn gasgliad syml o awgrymiadau a newidyn i storio mynegai pen y pentwr.
Pan gaiff ei gychwyn, crëir amrywiaeth o 256 o elfennau. Os caiff mwy o awgrymiadau eu gwthio i'r pentwr, mae ei faint yn cynyddu gan y 256 o elfennau nesaf. Yn unol â hynny, wrth dynnu elfennau o'r pentwr, mae ei faint yn cael ei addasu.

Mae'r VM yn defnyddio sawl pentyrrau:

  1. Prif bentwr.
  2. Pentwr ar gyfer storio pwyntiau dychwelyd.
  3. Pentwr casglwr sbwriel.
  4. Ceisiwch / dal / blocio pentwr triniwr o'r diwedd.

Cysonion a Newidynnau

Mae'r un hon yn syml. Mae cysonion yn cael eu trin mewn darn bach o god ar wahân ac maent ar gael mewn cymwysiadau yn y dyfodol trwy gyfeiriadau sefydlog. Mae newidynnau yn amrywiaeth o awgrymiadau o faint penodol, mae mynediad i'w gelloedd yn cael ei gyflawni trwy fynegai - h.y. cyfeiriad sefydlog. Gellir gwthio newidynnau i ben y pentwr neu eu darllen oddi yno. A dweud y gwir, oherwydd Er bod ein newidynnau yn y bôn yn storio awgrymiadau i werthoedd yng nghof VM, mae'r iaith yn cael ei dominyddu gan weithio gydag awgrymiadau ymhlyg.

Casglwr sbwriel

Yn fy VM mae'n lled-awtomatig. Y rhai. y datblygwr ei hun sy'n penderfynu pryd i alw'r casglwr sbwriel. Nid yw'n gweithio gan ddefnyddio rhifydd pwyntydd rheolaidd, fel yn Python, Perl, Ruby, Lua, ac ati. Fe'i gweithredir trwy system farcio. Y rhai. pan fwriedir neilltuo gwerth dros dro i newidyn, mae pwyntydd i'r gwerth hwn yn cael ei ychwanegu at bentwr y casglwr sbwriel. Yn y dyfodol, mae'r casglwr yn rhedeg yn gyflym trwy'r rhestr awgrymiadau a baratowyd eisoes.

Trin ceisio/dal/blociau o'r diwedd

Fel mewn unrhyw iaith fodern, mae ymdrin ag eithriadau yn elfen bwysig. Mae'r craidd VM wedi'i lapio mewn bloc ceisio..catch, a all ddychwelyd i weithredu cod ar ôl dal eithriad trwy wthio rhywfaint o wybodaeth amdano ar y pentwr. Yn y cod cais, gallwch ddiffinio ceisio / dal / blociau o god o'r diwedd, gan nodi pwyntiau mynediad wrth ddal (triniwr eithriad) ac yn olaf / diwedd (diwedd y bloc).

Aml-edau

Fe'i cefnogir ar lefel VM. Mae'n syml ac yn gyfleus i'w ddefnyddio. Mae'n gweithio heb system ymyrraeth, felly dylid gweithredu'r cod mewn sawl edafedd sawl gwaith yn gyflymach, yn y drefn honno.

Llyfrgelloedd allanol ar gyfer VMs

Nid oes unrhyw ffordd i wneud heb hyn. Mae VM yn cefnogi mewnforion, yn debyg i sut mae'n cael ei weithredu mewn ieithoedd eraill. Gallwch ysgrifennu rhan o'r cod mewn Stwnsh a rhan o'r cod mewn ieithoedd brodorol, yna eu cysylltu ag un.

Cyfieithydd o iaith Stwnsh lefel uchel i god beit ar gyfer VMs

Iaith ganolradd

Er mwyn ysgrifennu cyfieithydd yn gyflym o iaith gymhleth i god VM, datblygais iaith ganolradd gyntaf. Y canlyniad oedd golygfa ofnadwy tebyg i gydosodwr nad oes unrhyw bwynt penodol i'w ystyried yma. Ni fyddaf ond yn dweud bod y cyfieithydd ar y lefel hon yn prosesu'r rhan fwyaf o gysonion a newidynnau, yn cyfrifo eu cyfeiriadau sefydlog a chyfeiriadau pwyntiau mynediad.

Pensaernïaeth cyfieithydd

Wnes i ddim dewis y bensaernïaeth orau ar gyfer gweithredu. Nid yw'r cyfieithydd yn adeiladu coeden god, fel y mae cyfieithwyr eraill yn ei wneud. Mae'n edrych ar ddechrau'r strwythur. Y rhai. os yw'r darn o god sy'n cael ei ddosrannu'n edrych fel “tra bod <condition>:”, yna mae'n amlwg mai lluniad dolen tra yw hwn ac mae angen ei brosesu fel lluniad dolen ychydig. Rhywbeth fel cas switsh cymhleth.

Diolch i'r datrysiad pensaernïol hwn, nid oedd y cyfieithydd yn gyflym iawn. Fodd bynnag, mae rhwyddineb ei addasu wedi cynyddu'n sylweddol. Ychwanegais y strwythurau angenrheidiol yn gyflymach nag y gallai fy nghoffi oeri. Gweithredwyd cefnogaeth OOP llawn mewn llai nag wythnos.

Optimeiddio cod

Yma, wrth gwrs, gallai fod wedi cael ei weithredu'n well (a bydd yn cael ei weithredu, ond yn ddiweddarach, cyn gynted ag y bydd rhywun yn dod o gwmpas iddo). Hyd yn hyn, dim ond sut i dorri cod nas defnyddiwyd, cysonion a mewnforion o'r cynulliad y mae'r optimizer yn ei wybod. Hefyd, mae un cysonion gyda'r un gwerth yn cael eu disodli gan un. Dyna i gyd.

Iaith stwnsh

Cysyniad sylfaenol o iaith

Y prif syniad oedd datblygu'r iaith fwyaf ymarferol a syml bosibl. Credaf fod y datblygiad yn ymdopi â’i dasg gyda chlec.

Blociau cod, gweithdrefnau a swyddogaethau

Mae pob lluniad yn yr iaith yn cael ei agor gyda cholon. : ac yn cael eu cau gan y gweithredwr diwedd.

Mae gweithdrefnau a swyddogaethau yn cael eu datgan fel proc a func, yn y drefn honno. Rhestrir y dadleuon mewn cromfachau. Mae popeth fel y mwyafrif o ieithoedd eraill.

Gweithredwr dychwelyd gallwch ddychwelyd gwerth o swyddogaeth, gweithredwr torri yn caniatáu ichi adael y weithdrefn / swyddogaeth (os yw y tu allan i'r dolenni).

Enghraifft o god:

...

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

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

Dyluniadau â Chymorth

  • Dolenni: ar gyfer..diwedd, tra..diwedd, tan..diwedd
  • Amodau: os..[arall..]diwedd, switsh..[achos..diwedd..][arall..]diwedd
  • Dulliau: proc <enw>():... diwedd, func <enw>():... diwedd
  • Label & goto: <enw> :, neidio <enw>
  • Rhifau rhif ac araeau cyson.

Newidynnau

Gall y cyfieithydd eu pennu'n awtomatig, neu os bydd y datblygwr yn ysgrifennu var cyn eu diffinio.

Enghreifftiau cod:

a ?= 10
b ?= a + 20

var a = 10, b = a + 20

Cefnogir newidynnau byd-eang a lleol.

OOP

Wel, rydyn ni wedi dod at y pwnc mwyaf blasus. Mae Mash yn cefnogi'r holl baradeimau rhaglennu sy'n canolbwyntio ar wrthrych. Y rhai. dosbarthiadau, etifeddiaeth, polymorphism (gan gynnwys deinamig), adlewyrchiad awtomatig deinamig a mewnsylliad (llawn).

Heb ragor o wybodaeth, mae'n well rhoi enghreifftiau cod yn unig.

Dosbarth syml a gweithio gydag ef:

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

Bydd allbwn: 30.

Etifeddiaeth ac amlffurfiaeth:

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

Bydd allbwn: 60.

Beth am polymorphism deinamig? Ydy, dyma fyfyrio!:

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

Bydd allbwn: 60.

Nawr, gadewch i ni gymryd eiliad i fewnosod ar gyfer gwerthoedd a dosbarthiadau syml:

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

Will allbwn: gwir, gwir.

Ynglŷn â gweithredwyr aseiniadau ac awgrymiadau penodol

Defnyddir y gweithredydd ?= i aseinio newidyn pwyntydd i werth yn y cof.
Mae'r gweithredwr = yn newid gwerth yn y cof gan ddefnyddio pwyntydd o newidyn.
Ac yn awr ychydig am awgrymiadau penodol. Fe wnes i eu hychwanegu at yr iaith fel eu bod yn bodoli.
@<newidyn> — cymerwch bwyntydd penodol at newidyn.
?<newidyn> — mynnwch newidyn fesul pwyntydd.
@= — aseinio gwerth i newidyn trwy bwyntydd penodol iddo.

Enghraifft o god:

uses <bf>
uses <crt>

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

Bydd allbwn: rhai rhif, 10, 11.

Ceisiwch...[dal..][o'r diwedd..]diwedd

Enghraifft o god:

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

Cynlluniau ar gyfer y dyfodol

Rwy'n dal i edrych ac edrych ar GraalVM & Truffle. Nid oes gan fy amgylchedd amser rhedeg gasglwr JIT, felly o ran perfformiad dim ond gyda Python y mae'n gystadleuol. Rwy'n gobeithio y byddaf yn gallu gweithredu casgliad JIT yn seiliedig ar GraalVM neu LLVM.

ystorfa

Gallwch chi chwarae gyda'r datblygiadau a dilyn y prosiect eich hun.

Safle
Ystorfa ar GitHub

Diolch am ddarllen hyd y diwedd os gwnaethoch chi.

Ffynhonnell: hab.com

Ychwanegu sylw