
Préface
Cette langue a Ă©tĂ© dĂ©veloppĂ©e par moi Ă des fins Ă©ducatives. Je ne le considĂšre pas (pour le moment) comme un langage parfaitement dĂ©veloppĂ©, mais peut-ĂȘtre qu'Ă l'avenir il pourra rivaliser avec ses concurrents.
Si vous souhaitez l'essayer vous-mĂȘme en action - tĂ©lĂ©chargez
le rĂ©fĂ©rentiel du projet, vous y trouverez la version assemblĂ©e du projet ou l'assemblez vous-mĂȘme, pour votre systĂšme d'exploitation.
Cet article décrira un petit manuel de projet et considérera la syntaxe du langage.
Variables et pointeurs implicites
Dans Mash, chaque variable stocke un pointeur sur un objet en mémoire. Lors du transfert de variables vers des méthodes, de l'obtention d'un résultat ou de simples manipulations avec celles-ci, le travail est effectué avec des objets en mémoire par des pointeurs vers eux.
C'est-à -dire dans le code suivant, un tableau sera transmis à la méthode p (arr) comme pointeur vers un objet déjà créé précédemment.
proc p(arr): ... end proc main(): arr ?= [1, 2, 3, 4, 5] p(arr) end
La présence de pointeurs dans le langage, à la fois explicites et implicites, à mon avis, lui donne une flexibilité et des fonctionnalités supplémentaires, bien que dans certains cas, il contribue à la génération d'erreurs.
Variables temporaires et garbage collector
Contrairement aux langages de programmation similaires, Mash dispose d'un récupérateur de déchets semi-automatique basé sur le mécanisme des étiquettes de valeur temporelle, plutÎt que de compter les pointeurs.
C'est-Ă -dire le dĂ©veloppeur dĂ©cide lui-mĂȘme quand vider la mĂ©moire des ordures et peut Ă©galement le faire manuellement, dans certains cas.
Le garbage collection est appelé à l'aide de gc () et libÚre de la mémoire sous tous les objets temporaires.
De nombreuses actions simples avec des variables s'accompagnent de la création d'objets temporaires en mémoire.
Le développeur peut déclarer explicitement une allocation de mémoire pour continuer à travailler avec elle, c'est-à -dire déclarer des variables pour une utilisation à long terme.
Exemples de création d'une variable temporaire:
x ?= 10
Et les variables non marquées pour le garbage collector:
x ?= new(10) var x2 = 20
Un exemple d'utilisation de gc ():
while a > b: doSomething(a, b) gc() end
La mĂ©moire peut Ă©galement ĂȘtre libĂ©rĂ©e manuellement:
var a = 10, b = 20, c = 30 ... Free(a, b, c)
Zones de visibilité variable
Les variables dans Mash peuvent ĂȘtre dĂ©clarĂ©es localement et globalement.
Les variables globales sont déclarées entre les méthodes, via l'instruction var. Local - méthodes internes en aucune façon.
Types de données
Dans Mash, la frappe dynamique. DĂ©tectez / remplacez automatiquement les types de donnĂ©es pour les nombres non signĂ©s et signĂ©s, les nombres fractionnaires et les chaĂźnes. De plus, Ă partir de types de donnĂ©es simples, les tableaux (y compris ceux Ă plusieurs niveaux), les types d'Ă©numĂ©ration (presque les mĂȘmes que les tableaux), les mĂ©thodes, un type de donnĂ©es logique et peut-ĂȘtre tout est pris en charge.
Exemples de code:
x ?= 10 x += 3.14 x *= "3" x /= "2,45" x ?= [1, 2, 3.33, func1(1, 2, 3), "String", ["Enum type", 1, 2, 3], "3,14"]
L'introspection vous permet de déterminer le type de variable dont vous avez besoin:
if typeof(x) == TypeInt: ... end
Tableaux et énumérations
Les tùches rares n'obligent pas le développeur à déclarer le tableau suivant dans le code.
Mash prend en charge les tableaux composĂ©s d'un nombre arbitraire de niveaux, + les tableaux peuvent ĂȘtre quelque chose comme des arbres, c'est-Ă -dire les tailles des sous-niveaux peuvent varier sur un sous-niveau.
Exemples de déclarations de tableaux et d'énumérations:
a ?= new[10][20] var b = new[10][20] c ?= [1, [], 3, 3.14, "Test", [1, 2, 3, 4, 5], 7.7, a, b, ["77", func1()]] var d = [1, 2, 3]
Les objets déclarés via le nouvel opérateur ne sont pas marqués pour le garbage collector.
Les tableaux, comme les objets normaux en mémoire, sont libérés en appelant Free ()
Un tel travail avec des transferts est assez pratique.
Par exemple, vous pouvez passer à des méthodes ou en renvoyer de nombreuses valeurs d'une variable:
func doSomething(a, b, c): return [a+c, b+c] end
Opérateurs d'affectation
Il existe jusqu'à 3 opérateurs d'affectation dans Mash.
- ? =
Attribue une variable Ă un pointeur sur un objet (si une variable est dĂ©clarĂ©e mais ne stocke pas de pointeur sur un objet en mĂ©moire, cet opĂ©rateur doit ĂȘtre utilisĂ© pour lui attribuer une valeur). - =
Affectation normale. Attribue Ă un objet par pointeur dans une variable la valeur d'un autre objet. - @ =
Attribue une valeur à un objet par un pointeur explicite sur cet objet (cela sera discuté plus tard).
Opérations mathématiques et logiques
Liste des opérations mathématiques et logiques actuellement prises en charge:
Pointeurs explicites
Il semblerait, pourquoi sont-ils nĂ©cessaires s'il n'y a pas de pointeurs explicites? Par exemple, pour vĂ©rifier si les variables A et B stockent des pointeurs vers le mĂȘme objet en mĂ©moire.
- @ - récupÚre un pointeur sur un objet et le place dans une variable, comme un objet.
- ? - récupérer l'objet par pointeur depuis l'objet dans la variable.
Un exemple: a ?= ?b
Procédures et fonctions
J'ai décidé de faire la séparation du langage des méthodes de retour des valeurs dans les procédures et les fonctions (comme en Pascal).
Les déclarations de méthode sont faites comme les exemples suivants:
proc SayHello(arg1, arg2, argN): println("Hello, ", arg1, arg2, argN) end func SummIt(a, b): return a + b end
Constructions linguistiques
Un exemple de construction if..else..end.
if <>: ... else: ... end
Pour boucle.
for([]; <>; [ ]): ... end
Alors. La condition est vérifiée avant itération.
whilst <>: ... end
Tandis que. Une boucle qui diffÚre de while en ce que la condition est vérifiée aprÚs l'itération.
until <>: ... end
switch..case..end..else..end ... est une construction familiÚre pour créer des branches logiques.
switch <>: case < 1>: ... end case < 2>: ... end else: ... end
Classes et éléments du langage OOP
Mash implémente le support des classes, l'héritage, l'introspection et la réflexion dynamiques, le polymorphisme. C'est-à -dire Un ensemble standard de langages de script est pris en charge.
Considérons une simple déclaration de classe:
class MyClass: var a, b proc Create, Free func SomeFunction end
Une déclaration de classe ne contient pas d'implémentations des méthodes qui y sont déclarées.
Le constructeur de la classe est la méthode Create. En tant que destructeur - gratuit.
Une fois la classe déclarée, vous pouvez décrire l'implémentation de ses méthodes:
proc MyClass::Create(a, b): $a ?= new(a) $b ?= new(b) end proc MyClass::Free(): Free($a, $b, $) end func MyClass::SomeFunction(x): return ($a + $b) / x end
Vous remarquerez peut-ĂȘtre le symbole $ Ă certains endroits du code - avec ce symbole, j'ai simplement raccourci le long this->. C'est-Ă -dire code:
return ($a + $b) / x ... Free($a, $b, $)
Ăquivalent Ă ce code:
return (this->a + this->b) / x ... Free(this->a, this->b, this)
Il contient un pointeur sur une instance de la classe pour le compte de laquelle la méthode de cette classe est appelée.
Afin d'hériter des fonctionnalités d'une classe, vous devez décrire la déclaration d'une nouvelle classe de cette maniÚre:
class MySecondClass(MyClass): func SomeFunction end func MySecondClass::SomeFunction(x): return ($a - $b) / x end
MySecondClass - aura un constructeur et un destructeur de sa fonction ancĂȘtre + SomeFunction, que possĂšde la classe ancĂȘtre, est Ă©crasĂ© par une fonction d'une nouvelle classe.
Pour créer des instances de classe, le nouvel opérateur existe.
Exemples de code:
a ?= new MyClass //
b ?= new MyClass(10, 20) //
Le type d'une instance d'une classe peut ĂȘtre dĂ©terminĂ© lors de la crĂ©ation de cette instance; en consĂ©quence, la conversion de type est absente dans le langage.
L'introspection vous permet de déterminer le type d'instance de classe, exemple de code:
x ?= new MyClass(10, 20) ... if x->type == MyClass: // -... end
Parfois, vous devez vous tourner vers une fonction de classe et la remplacer par une nouvelle. Exemple de code:
func class::NewSomeFunction(x): return $x * $y * x end ... x ?= new MyClass(10, 20) x->SomeFunction ?= class::NewSomeFunction x->SomeFunction(33) // NewSomeFunction, .
Conclusion
Dans cet article, j'ai essayé de présenter à ma création d'éventuelles personnes intéressées.
Merci d'avoir lu. En attente de commentaires.