Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: Writing a Programming Language  (Read 1295 times)

kytuzian

  • Bay Watcher
    • View Profile
    • Kytuzian - Youtube
Writing a Programming Language
« on: June 26, 2015, 02:05:49 pm »

I've been thinking about creating a programming language, mostly for my own learning/fun but I also want to be able to actually program in it. To be honest, I'm not really sure if I'll end up finishing it, but I plan to try.

Here is the idea:

The language is primarily based on sets and their manipulation. Lazy evaluation, static typing, functional (ish).

Sets are going to be represented by a list of conditions that specify what fits into the set, unless it's just a set of values ({1,2,6} or {"green", "red", "blue"}). The conditions will be evaluated from right to left.

For example, the integers 1 - 10:

Code: [Select]
{a | a <= 10, a in N}

where N is the set of natural numbers. All elements that fit the condition <= 10 will be evaluated to the left hand side (in this case, just a). This is intended to be pretty much the same as set-builder notation.

Creating a set and storing it:

Code: [Select]
let S = {a^2 | a in N} #This is a comment. Squares of all the natural numbers.

S will be immutable, and will give an error if you try to change it.

Code: [Select]
let S = {2} #Error! Immutable value

#Create a set of all the integers
let Z = {0} U { n, -n | n in N } #Integers is 0 and then every negative/positive natural number.

U means union, by the way.

Functions defined as follows:
Code: [Select]
fib :: Natural -> Natural
fib := fib 1 = 1
fib := fib 2 = 1
fib := fib n = (fib (n - 1)) + (fib (n - 2))
done

This means that fib is a function that takes a natural number and returns a natural number. There's no particular reason I'm using :=, but I feel like it's a good fit. There are three definitions of fib, one where it is followed by a 1, another where it is followed by a 2, and everything else. The reason for the strange double definition (fib := fib n) and not just (fib n) is shown below:

Code: [Select]
#Creating a type
type Vector<T> uses
    self :: Set #Vectors are themselves just sets with some operations defined on them.

    + :: Vector<T> -> Vector<T> -> Vector<T>
    + := a + b = {a_self_i + b_self_i | i < (cardinality a), i in N}
    done
done

#Now we can use this like so:
let v1 = Vector<Integer> {1, 2, 3}
let v2 = Vector<Integer> {-2, 4, -6}

let vsum = v1 + v2 #{-1, 6, -3}
As you can see, the strange definition allows us to easily define infix functions (or however you want them to be written). Evaluation will still be left to right, but this allows the function to specify where it's arguments are. It seems like a good idea. Feel free to call me dumb if it is.

So yeah. There's the basic idea. If any of the syntax seems strange, clunky, or confusing, just let me know. In fact, please let me know, that's why I'm posting it.
« Last Edit: June 26, 2015, 02:17:12 pm by kytuzian »
Logged

Dutrius

  • Bay Watcher
  • No longer extremely unavailable!
    • View Profile
    • Arcanus Technica
Re: Writing a Programming Language
« Reply #1 on: June 27, 2015, 05:29:41 pm »

PTW.

Looks interesting.
Logged
No longer extremely unavailable!
Sig text
ArcTech: Incursus. On hold indefinitely.

kytuzian

  • Bay Watcher
    • View Profile
    • Kytuzian - Youtube
Re: Writing a Programming Language
« Reply #2 on: June 27, 2015, 06:35:42 pm »

Alright so I came up with some more details and basic idea of how this is going to work. I'm writing it in C++, and the idea is to compile this language to C++ as well. So, essentially, this is a translator to C++, which can then be compiled to get a working executable. I'm doing this for a few reasons:

  • I think it will be easier (very important).
  • It's interesting (to me at least).
  • It should run much more quickly than if I wrote an interpreter for it.

I also wrote a basic lexer for it, that turns things like

Code: [Select]
let S = {a^2 | a in N} #This is a comment. Squares of all the natural numbers.

into

Code: [Select]
{ type: "keyword", raw: "let", flag: false }
{ type: "identifier", raw: "S", flag: false }
{ type: "operator", raw: "=", flag: false }
{ type: "grouping", raw: "{", flag: true }
{ type: "identifier", raw: "a", flag: false }
{ type: "operator", raw: "^", flag: false }
{ type: "number", raw: "2", flag: false }
{ type: "punctuation", raw: "|", flag: false }
{ type: "identifier", raw: "a", flag: false }
{ type: "keyword", raw: "in", flag: false }
{ type: "identifier", raw: "N", flag: false }
{ type: "grouping", raw: "}", flag: false }

Also:
PTW.

Looks interesting.

Thanks, do you have any comments about the syntax or anything?

kytuzian

  • Bay Watcher
    • View Profile
    • Kytuzian - Youtube
Re: Writing a Programming Language
« Reply #3 on: June 29, 2015, 10:20:03 pm »

Alright I have now written the basic form of the expression parser, which takes tokens and organizes them into what I believe is called an abstract syntax tree by those fancy computery types.

For example:
Code: [Select]
let S = {a | a < 10, a in N}

Becomes:
Code: [Select]
{
    type: "let",
    head:
        { type: "identifier", raw: "S", flag: false, line: 1 }
    body:
        {
            type: "set",
            head:
                { type: "identifier", raw: "a", flag: false, line: 1 }
            body:
                {
                    type: "condition",
                    head:
                    body:
                        {
                            type: "base",
                            head: NULL,
                            body: NULL,
                            tokens:
                                { type: "identifier", raw: "a", flag: false, line: 1 }
                                { type: "operator", raw: "<", flag: false, line: 1 }
                                { type: "number", raw: "10", flag: false, line: 1 }
                        }
                    tokens: {}
                }
                {
                    type: "condition",
                    head:
                    body:
                        {
                            type: "base",
                            head: NULL,
                            body: NULL,
                            tokens:
                                { type: "identifier", raw: "a", flag: false, line: 1 }
                                { type: "keyword", raw: "in", flag: false, line: 1 }
                                { type: "identifier", raw: "N", flag: false, line: 1 }
                        }
                    tokens: {}
                }
            tokens: {}
        }
    tokens: {}
}

Puzzlemaker

  • Bay Watcher
    • View Profile
Re: Writing a Programming Language
« Reply #4 on: June 30, 2015, 09:29:05 am »

What are you going to use for the actual parsing?  Are you going to use a tool or roll your own?  I would suggest a tool, personally.
Logged
The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.

kytuzian

  • Bay Watcher
    • View Profile
    • Kytuzian - Youtube
Re: Writing a Programming Language
« Reply #5 on: June 30, 2015, 12:44:35 pm »

What are you going to use for the actual parsing?  Are you going to use a tool or roll your own?  I would suggest a tool, personally.

I'm not entirely sure yet, I've just begun looking into that today. I probably should have done that before, I but I really felt like just kind of starting, and I didn't spend that much time on it, so if I have to redo it I'll survive. Something like this (https://en.wikipedia.org/wiki/LR_parser) sounds promising, but I really have no idea. If you have any ideas that'd be amazing.

Puzzlemaker

  • Bay Watcher
    • View Profile
Re: Writing a Programming Language
« Reply #6 on: June 30, 2015, 03:56:40 pm »

Depends... LLVM is pretty cool looking, but I havn't ever used it.

Yacc or Bison is also pretty good, and I have used it before.
Logged
The mark of the immature man is that he wants to die nobly for a cause, while the mark of the mature man is that he wants to live humbly for one.

Antsan

  • Bay Watcher
    • View Profile
Re: Writing a Programming Language
« Reply #7 on: July 05, 2015, 04:25:33 am »

PTW

Maybe you might want to take a look at LLVM.
Logged
Taste my Paci-Fist

kytuzian

  • Bay Watcher
    • View Profile
    • Kytuzian - Youtube
Re: Writing a Programming Language
« Reply #8 on: July 06, 2015, 03:42:43 pm »

PTW

Maybe you might want to take a look at LLVM.

Depends... LLVM is pretty cool looking, but I havn't ever used it.

Yacc or Bison is also pretty good, and I have used it before.

Thanks for the suggestions. I'm also looking at ANTLR (antlr.org/) because it looks pretty easy to use. Either way, I think that I'm going to scrap the whole thing and restart.

Antsan

  • Bay Watcher
    • View Profile
Re: Writing a Programming Language
« Reply #9 on: July 06, 2015, 04:39:05 pm »

Oh, LLVM isn't actually for parsing, it's for code generation, if I got that right. I see you said you were compiling to C++, so you probably aren't really interested in that.

I remember that somewhere (Learn You A Haskell For Grat Good, maybe?) I read that monads over lists where basically nondeterministic computation.
That is, you had functions that take some object of type a and then return lists of objects of type b. Taking lists of a and then appending the resulting lists of calling the function on any of the elements is basically nondeterminism, only that sometimes computations are done in double and order shouldn't really matter in nondeterministic computation. Lists without duplicates and ordering are sets. So, if you want to, you can make yours a language for nondeterministic computation.
Logged
Taste my Paci-Fist