
前言
该语言是我为教育目的而开发的。 我不认为它(目前)是一种完善的语言,但是也许将来它可以与竞争对手竞争。
如果您希望自己尝试使用它-下载项目
存储库 ,在其中可以找到适合您的OS的项目的组装版本或自己组装。
本文将介绍一个小型项目手册,并考虑该语言的语法。
变量和隐式指针
在Mash中,每个变量都将一个指向对象的指针存储在内存中。 当将变量传递给方法,获取结果或对其进行简单操作时,将通过指向它们的指针来处理内存中的对象。
即 在下面的代码中,数组将作为指向早先创建的对象的指针传递给p(arr)方法。
proc p(arr): ... end proc main(): arr ?= [1, 2, 3, 4, 5] p(arr) end
我认为,语言中无论是显式还是隐式的指针,都为它提供了更多的灵活性和功能性,尽管在某些情况下它会导致错误的产生。
临时变量和垃圾收集器
与类似的编程语言不同,Mash具有半自动垃圾收集器,该垃圾收集器基于时间值标签的机制,而不是对指针进行计数。
即 开发人员自己决定何时清除垃圾内存,在某些情况下也可以手动进行。
使用gc()调用垃圾收集,并从所有临时对象下释放内存。
许多带有变量的简单动作都会在内存中创建临时对象。
开发人员可以显式声明一个内存分配以进行进一步的处理,即 声明变量以供长期使用。
创建临时变量的示例:
x ?= 10
和未标记为垃圾收集器的变量:
x ?= new(10) var x2 = 20
使用gc()的示例:
while a > b: doSomething(a, b) gc() end
也可以手动释放内存:
var a = 10, b = 20, c = 30 ... Free(a, b, c)
可变可见区
Mash中的变量可以在本地和全局声明。
通过var语句在方法之间声明全局变量。 本地-内部方法以任何方式。
资料类型
在Mash中,动态输入。 自动检测/覆盖无符号和有符号数字,小数数字和字符串的数据类型。 另外,从简单的数据类型开始,数组(包括多级数组),枚举类型(与数组几乎相同),方法,逻辑数据类型,也许所有内容都受支持。
代码示例:
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"]
内省使您可以确定所需的变量类型:
if typeof(x) == TypeInt: ... end
数组和枚举
稀有任务不会强制开发人员在代码中声明下一个数组。
混搭支持由任意数量的级别组成的数组,+数组可以像树一样,即 子级别的大小可能在一个子级别上有所不同。
数组和枚举的声明示例:
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]
通过new运算符声明的任何对象都不会标记为垃圾回收器。
数组与内存中的常规对象一样,可以通过调用Free()来释放
这样的转移工作非常方便。
例如,您可以传递给方法或从中返回一个变量的许多值:
func doSomething(a, b, c): return [a+c, b+c] end
赋值运算符
Mash中有多达3个赋值运算符。
- ?=
将变量分配给指向对象的指针(如果声明了变量但未在内存中存储指向对象的指针,则必须使用此运算符为其分配值)。 - =
正常分配。 通过变量中的指针将另一个对象的值分配给对象。 - @ =
通过指向该对象的显式指针为该对象分配值(稍后将对此进行讨论)。
数学和逻辑运算
当前支持的数学和逻辑运算列表:
显式指针
似乎,如果没有显式指针,为什么需要它们? 例如,检查变量A和B是否在内存中存储指向同一对象的指针。
- @ -获取指向对象的指针,并将其放入变量(如对象)中。
- ? -通过指针从变量中的对象获取对象。
一个例子: a ?= ?b
程序和功能
我决定对将值返回到过程和函数的方法进行语言分隔(如Pascal中一样)。
方法声明类似于以下示例:
proc SayHello(arg1, arg2, argN): println("Hello, ", arg1, arg2, argN) end func SummIt(a, b): return a + b end
语言构造
if..else..end构造示例。
if <>: ... else: ... end
对于循环。
for([]; <>; [ ]): ... end
一会儿 在迭代之前检查条件。
whilst <>: ... end
虽然。 循环不同于while循环,是在迭代后检查条件。
until <>: ... end
switch..case..end..else..end ...是用于创建逻辑分支的熟悉结构。
switch <>: case < 1>: ... end case < 2>: ... end else: ... end
OOP语言的类和元素
Mash实现了对类,继承,动态自省和反射,多态的支持。 即 支持一组标准的脚本语言。
考虑一个简单的类声明:
class MyClass: var a, b proc Create, Free func SomeFunction end
类声明不包含在其中声明的方法的实现。
该类的构造函数是Create方法。 作为破坏者-免费。
在类声明之后,您可以描述其方法的实现:
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
您可能会在代码的某些位置注意到$符号-使用这个符号我只是缩短了长的this->。 即 代码:
return ($a + $b) / x ... Free($a, $b, $)
等效于以下代码:
return (this->a + this->b) / x ... Free(this->a, this->b, this)
它包含一个指向该类实例的指针,该类的方法代表该实例被调用。
为了继承类的功能,您需要以这种方式描述新类的声明:
class MySecondClass(MyClass): func SomeFunction end func MySecondClass::SomeFunction(x): return ($a - $b) / x end
MySecondClass-将从祖先类拥有的祖先+ SomeFunction函数获得构造函数和析构函数,而该函数将被新类的函数覆盖。
要创建类实例,必须存在new运算符。
代码示例:
a ?= new MyClass //
b ?= new MyClass(10, 20) //
创建实例时可以确定类的实例的类型;因此,该语言中不存在类型转换。
内省使您可以确定类实例的类型,代码示例:
x ?= new MyClass(10, 20) ... if x->type == MyClass: // -... end
有时您需要使用一个类函数,并用新的函数覆盖它。 代码示例:
func class::NewSomeFunction(x): return $x * $y * x end ... x ?= new MyClass(10, 20) x->SomeFunction ?= class::NewSomeFunction x->SomeFunction(33) // NewSomeFunction, .
结论
在本文中,我试图向我的创作介绍可能感兴趣的人。
感谢您的阅读。 等待评论。