aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: e4d44897e5cf9f94dae0f98324b801408bd7c991 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<div style="width: 30%">
![Elymas logo](elymas.svg) (Logo by @blinry)
</div>

*Just because I'm not following the true path, doesn't mean I can't get it to work.*

[![Build Status](https://travis-ci.org/Drahflow/Elymas.svg?branch=master)](https://travis-ci.org/Drahflow/Elymas)

Examples
--------

A programming language...

    1 dump
    # 0000000000000001

... stack based programming language ...

    1 2 add dump
    # 0000000000000003

... with array support ...

    [ 1 2 ] dump
    # [
    #   0000000000000001
    #   0000000000000002
    # ]

... did I mention array support ...

    2 [ 1 2 ] add dump
    [ 0 1 ] [ 1 2 ] add dump
    # [
    #   0000000000000003
    #   0000000000000004
    # ]
    # [
    #   0000000000000001
    #   0000000000000003
    # ]

... user definable functions ...

    { 2 add } /addTwo deffst
    1 addTwo dump
    # 0000000000000003

... variables ...
    
    2 ==two
    1 two add dump
    # 0000000000000003

... function objects ...

    { { 2 add } } /returnAddTwo deffst
    returnAddTwo /addTwo deffst
    1 addTwo dump
    # 0000000000000003

... closures ...

    { 2 ==two { two add } } /returnAddTwo deffst
    returnAddTwo /addTwo deffst
    1 addTwo dump
    # 0000000000000003

... structured data types ...

    <
      1 ==one
      2 ==two
    > ==struct

    struct keys dump
    struct .two dump

    # [
    #   "one"
    #   "two"
    # ]
    # 0000000000000002

... and more.

    "Elymas" { "(..)(.*)" regex } |dump loop

    # "El"
    # "ym"
    # "as"


Technical Pecularities
----------------------

* no runtime interpreter, executes real assembly
  * same binary both interpretes and compiles
* freeze arbitrary program states to ELF-binaries
* self hosted via `{ "/dev/stdin" include }' "interpreter" sys .freeze`
  * yes, this works and generates a stand-alone interpreter/compiler
  * bootstraps from perl
    * no perl left in final binaries
* macro support
* names carry information about being constant or constantly having the same type each resolution
  * just-too-late opcode optimization
  * so at least one resolution is guaranteed to have taken place
  * can declare names any time before first usage
* assembly optimizer realized as a loadable library
  * yes, it does optimize itself while running
* regex-engine written in the language itself
* source includes an assembler for 64bit x86


Features
--------

* non-braindead stack manipulation, e.g. `-021` specifies "top element, then third, then second"
* concatenative language syntax, e.g. `data modifyOne modifyTwo modifyThree`
* trivial to build DSLs
* compact code
  * more readable than APL though
  * unless you don't want it to be
* acceptable performance (and you can always switch to assembly if necessary)
* I actually use it for non-trivial projects

Documentation
-------------

Please see [the tutorial](doc/tutorial.md) for an introduction and further documentation.