Anybody here made their own programming language?

  • 134 Replies
  • 24556 Views
*

FlatAssembler

  • 672
  • Not a FE-er
Re: Anybody here made their own programming language?
« Reply #120 on: January 19, 2023, 12:02:23 PM »
Writing shell scripts has left a very bad impression on me. I have written two short scripts, and I have had to ask no less than three StackOverflow questions (Fortunately, none of them reduced my reputation, and one of them received two upvotes.). One would think that checking whether a program with some name is available is one of the most common things one would like to do in a shell script. Nonetheless, doing that is very complicated. And two times in two short scripts, I had to rely on truly mysterious fixes. I've written a rant about it on my blog:
Oh, and understand that you will sometimes have to apply fixes which you have no idea how they work. You will get a lot further by being empirical than by being a rationalist and only relying on things you understand. This is especially true when writing shell scripts, although it's also somewhat true in other types of programming. When writing a shell script to download, compile and run Analog Clock in AEC for x86, I ran into a problem that, on recent versions of Debian Linux, the linker insists that "-lm", the option for linking in the math library, is put after the source files, and it outputs some confusing error message if it's put before the source files. A rationalist solution would be to try to implement the math functions that Duktape invokes yourself, like I've implemented them in my programming language when writing Analog Clock for WebAssembly. Instead, I did a bit of Googling, and found a way nicer solution: put "-lm" after the source files, and not before them. I do not understand how it works, but I can empirically say it does work. You can read the zero9178's explanation for that if you are interested, I do not fully understand it either, and I probably know more about compiler theory than most programmers. And when writing a shell script to download, compile and run Analog Clock in AEC for WebAssembly, I realized that the code my AEC-to-WebAssembly compiler outputs works only on NodeJS 11 and newer, because it relies on WebAssembly global variables. So, I decided to warn the user if they have installed NodeJS that's older than NodeJS 11. So, I wrote "node_version=$(node -v)" to store the NodeJS version string into a variable called "node_version", so that I can extract the first number from it and act accordingly. That worked on Linux, but on Windows NodeJS outputted the error message "stdout is not a tty" instead of outputting the version string. I can't think of a rationalist work-around. But I was empirical, so I posted a question on StackOverflow, and I got the answer: on Windows, do "node_version=$(node.exe -v)". I almost did not try it, as it seemed so ridiculous. However, I was empirical enough that I tried it, and it somehow magically worked. I still have no idea how it works. It has something to do with the difference between how terminals work on Linux and how they work on Windows, but I don't understand the details. And like I've said, the fact that you sometimes stumble upon problems with truly mysterious fixes is true not only in shell scripting, but also in other types of programming, such as CSS. Look up the Internet Explorer 6 double-margin bug. Or how, when programming my PicoBlaze Simulator, I ran into a problem that the tooltips I made worked in Firefox but not in Chrome. In both cases, the fix seems so ridiculous that it's not even worth trying. For the Internet Explorer 6 double-margin bug, it was a mysterious bug in Internet Explorer 6. For the Chrome issue I've run into, the people on StackOverflow insist that Chrome is actually obeying the standard, while Firefox isn't. If so, the standard goes wildly against common sense here.  Programming is an empirical thing, but universities pretend it's a rationalist thing.
Fan of Stephen Wolfram.
This is my parody of the conspiracy theorists:
https://www.theflatearthsociety.org/forum/index.php?topic=71184.0
This is my attempt to refute the Flat-Earth theory:

*

FlatAssembler

  • 672
  • Not a FE-er
Re: Anybody here made their own programming language?
« Reply #121 on: March 06, 2023, 08:51:32 AM »
A few days ago, I managed to modify the part of the compiler that deals with inline assembly so that the assembly code it emits for `%variable` in inline assembly is now properly indented.

Today, I released the AECforWebAsembly v2.5.1, which contains the mentioned bugfix.
https://github.com/FlatAssembler/AECforWebAssembly/releases/tag/v2.5.1
Fan of Stephen Wolfram.
This is my parody of the conspiracy theorists:
https://www.theflatearthsociety.org/forum/index.php?topic=71184.0
This is my attempt to refute the Flat-Earth theory:

Re: Anybody here made their own programming language?
« Reply #122 on: March 06, 2023, 10:17:26 AM »
A few days ago, I managed to modify the part of the compiler that deals with inline assembly so that the assembly code it emits for `%variable` in inline assembly is now properly indented.
I for one am really glad that you logged on to give us this exciting and relevant news.
"I'm not entirely sure who this guy is, but JimmyTheLobster is clearly a genius.  Probably one of the smartest arthropods  of his generation." - JimmyTheCrab

Quote from: bulmabriefs144
The woke left have tried to erase photosynthesis

*

Username

  • Administrator
  • 17687
  • President of The Flat Earth Society
Re: Anybody here made their own programming language?
« Reply #123 on: March 15, 2023, 12:38:11 AM »
Here's a chatgpt created turing complete language in python.


class Interpreter:
    def __init__(self):
        self.vars = {}
        self.code = ''
        self.pointer = 0

    def run(self, program):
        self.code = program
        while self.pointer < len(self.code):
            current_char = self.code[self.pointer]
            if current_char == '>':
                self.pointer += 1
            elif current_char == '<':
                self.pointer -= 1
            elif current_char == '+':
                self.vars[self.pointer] = self.vars.get(self.pointer, 0) + 1
            elif current_char == '-':
                self.vars[self.pointer] = self.vars.get(self.pointer, 0) - 1
            elif current_char == '.':
                print(chr(self.vars.get(self.pointer, 0)), end='')
            elif current_char == ',':
                self.vars[self.pointer] = ord(input()[0])
            elif current_char == '[':
                if self.vars.get(self.pointer, 0) == 0:
                    loop_count = 1
                    while loop_count > 0:
                        self.pointer += 1
                        if self.code[self.pointer] == '[':
                            loop_count += 1
                        elif self.code[self.pointer] == ']':
                            loop_count -= 1
            elif current_char == ']':
                loop_count = 1
                while loop_count > 0:
                    self.pointer -= 1
                    if self.code[self.pointer] == '[':
                        loop_count -= 1
                    elif self.code[self.pointer] == ']':
                        loop_count += 1
                self.pointer -= 1
            self.pointer += 1


And the spec:

>: moves the pointer one position to the right
<: moves the pointer one position to the left
+: increments the value at the current pointer position on the tape
-: decrements the value at the current pointer position on the tape
.: prints the character represented by the value at the current pointer position on the tape
,: reads a character from the user and stores its ASCII value at the current pointer position on the tape
[: begins a loop. If the value at the current pointer position on the tape is zero, the interpreter jumps to the matching ] character.
]: ends a loop. If the value at the current pointer position on the tape is nonzero, the interpreter jumps back to the matching [ character.


This is a pretty standard programming problem for undergrads. First glance and it looks legitimate enough.
« Last Edit: March 15, 2023, 12:43:43 AM by Username »
The illusion is shattered if we ask what goes on behind the scenes.

Re: Anybody here made their own programming language?
« Reply #124 on: March 15, 2023, 04:06:27 AM »
Does python not have a switch statement?
"I'm not entirely sure who this guy is, but JimmyTheLobster is clearly a genius.  Probably one of the smartest arthropods  of his generation." - JimmyTheCrab

Quote from: bulmabriefs144
The woke left have tried to erase photosynthesis

*

Username

  • Administrator
  • 17687
  • President of The Flat Earth Society
Re: Anybody here made their own programming language?
« Reply #125 on: March 15, 2023, 10:03:57 AM »
Does python not have a switch statement?
They've added one recently I believe (2021). Honestly, if this was more complex and or not reliant on performance, a strategy pattern with a class factory would have been the right choice. I imagine most code doesn't leverage switches so it wasn't trained on it. A map is often used as well. What implementation would depend on the instruction set size.
« Last Edit: March 15, 2023, 11:56:13 AM by Username »
The illusion is shattered if we ask what goes on behind the scenes.

*

FlatAssembler

  • 672
  • Not a FE-er
Re: Anybody here made their own programming language?
« Reply #126 on: March 19, 2023, 01:21:18 PM »
Here's a chatgpt created turing complete language in python.


class Interpreter:
    def __init__(self):
        self.vars = {}
        self.code = ''
        self.pointer = 0

    def run(self, program):
        self.code = program
        while self.pointer < len(self.code):
            current_char = self.code[self.pointer]
            if current_char == '>':
                self.pointer += 1
            elif current_char == '<':
                self.pointer -= 1
            elif current_char == '+':
                self.vars[self.pointer] = self.vars.get(self.pointer, 0) + 1
            elif current_char == '-':
                self.vars[self.pointer] = self.vars.get(self.pointer, 0) - 1
            elif current_char == '.':
                print(chr(self.vars.get(self.pointer, 0)), end='')
            elif current_char == ',':
                self.vars[self.pointer] = ord(input()[0])
            elif current_char == '[':
                if self.vars.get(self.pointer, 0) == 0:
                    loop_count = 1
                    while loop_count > 0:
                        self.pointer += 1
                        if self.code[self.pointer] == '[':
                            loop_count += 1
                        elif self.code[self.pointer] == ']':
                            loop_count -= 1
            elif current_char == ']':
                loop_count = 1
                while loop_count > 0:
                    self.pointer -= 1
                    if self.code[self.pointer] == '[':
                        loop_count -= 1
                    elif self.code[self.pointer] == ']':
                        loop_count += 1
                self.pointer -= 1
            self.pointer += 1


And the spec:

>: moves the pointer one position to the right
<: moves the pointer one position to the left
+: increments the value at the current pointer position on the tape
-: decrements the value at the current pointer position on the tape
.: prints the character represented by the value at the current pointer position on the tape
,: reads a character from the user and stores its ASCII value at the current pointer position on the tape
[: begins a loop. If the value at the current pointer position on the tape is zero, the interpreter jumps to the matching ] character.
]: ends a loop. If the value at the current pointer position on the tape is nonzero, the interpreter jumps back to the matching [ character.


This is a pretty standard programming problem for undergrads. First glance and it looks legitimate enough.

That's... not quite a useful programming language.
Fan of Stephen Wolfram.
This is my parody of the conspiracy theorists:
https://www.theflatearthsociety.org/forum/index.php?topic=71184.0
This is my attempt to refute the Flat-Earth theory:

*

Username

  • Administrator
  • 17687
  • President of The Flat Earth Society
Re: Anybody here made their own programming language?
« Reply #127 on: March 20, 2023, 04:31:55 PM »
I suppose to those unfamiliar it might appear quite useless. Aside from being able to implement any algorithm you wish to throw at it, it's useful in a variety of applications including evolutionary computations, security, quantum computing, ai, and much much more. While perhaps not practical, it can serve these purposes and more. Of course, making a higher level language out of it is easy enough.
« Last Edit: March 20, 2023, 04:41:15 PM by Username »
The illusion is shattered if we ask what goes on behind the scenes.

*

Username

  • Administrator
  • 17687
  • President of The Flat Earth Society
Re: Anybody here made their own programming language?
« Reply #128 on: March 20, 2023, 04:44:14 PM »
And here's chatgpt's go at it. Untested, but again looks close enough to be debugable in an hour or two.

Quote
Language Syntax:

let x be <initial value> : creates a variable named x with an initial value on the tape
x = <value> : sets the value of variable x to the given value
print x : prints the value of variable x to the console
while x <op> <value>: begins a loop that runs while the value at variable x is less than the given value. The <op> operator can be <, >, <=, >=, or ==
end : ends a loop
Example program:

let x be 0
let y be 10
while x < y:
x = x + 1
print x
end

Compiled Turing machine code:

++++++++++[>++++++++++<-]>+++++[>++++++<-]>+++++[>+++++<-]>[<[-]<[-]<[-]<[-]<[-]<[-]<[-]<[-]>>>>>>[-<<<<<+>>>>>]<<<<<[-]>>.[-]<<[-]<[-]<[-]++++++++++[>++++++++++<-]>[-]>>.[-]<<[-]<[-]<<[-]<<[-]++++++++++[>++++++++++<-]>[-]>>.[-]<<[-]<[-]<<[-]+++++++++[>+++++<-]>[-]<<<<<[-]>>[-]<<.[-]<<[-]<<[-]


class Compiler:
    def __init__(self):
        self.code = ''
        self.pointer = 0

    def compile(self, program):
        self.code = ''
        self.pointer = 0

        # split program into lines and strip whitespace
        lines = [line.strip() for line in program.split('\n')]

        # initialize variables dictionary
        vars_dict = {}

        for line in lines:
            # parse let statements
            if line.startswith('let'):
                tokens = line.split()
                var_name = tokens[1]
                var_value = int(tokens[3])
                vars_dict[var_name] = var_value
                self.code += '>' * self.pointer
                self.code += '+' * var_value
                self.pointer += 1

            # parse assignment statements
            elif '=' in line:
                var_name, var_value = line.split('=')
                var_name = var_name.strip()
                var_value = int(var_value.strip())

                if var_name not in vars_dict:
                    raise ValueError(f"Undefined variable {var_name}")

                self.code += '>' * self.pointer
                self.code += '+' * (var_value - vars_dict[var_name])
                self.pointer += 1
                vars_dict[var_name] = var_value

            # parse print statements
            elif line.startswith('print'):
                var_name = line.split()[1]

                if var_name not in vars_dict:
                    raise ValueError(f"Undefined variable {var_name}")

                self.code += '>' * self.pointer
                self.code += '.'
                self.pointer += 1

            # parse while loops
            elif line.startswith('while'):
                var_name, op, value_str = line.split()[1:]
                value = int(value_str)

                if var_name not in vars_dict:
                    raise ValueError(f"Undefined variable {var_name}")

                # condition: variable value <op> value
                if op == '<':
                    op_code = '+'
                elif op == '>':
                    op_code = '-'
                elif op == '<=':
                    op_code = '[-]+'
                elif op == '>=':
                    op_code = '[-]-'
                elif op == '==':
                    op_code = '[-]'

                # start the loop
                self.code += '>' * self.pointer
                self.pointer += 1
                self.code += '['
                self.code += '>' * self.pointer
                self.code += op_code * (value - vars_dict[var_name])
                self.pointer += 1

            # parse end of loop
            elif line == 'end':
                self.code += '<' * self.pointer
                self.code += ']'
                self.pointer -= 1

        return self.code



compiler = Compiler()
program = """
let x be 0
let y be 10
while x < y:
    x = x + 1
    print x
end
"""
turing_code = compiler.compile(program)

interpreter = Interpreter()
interpreter.run(turing_code)
The illusion is shattered if we ask what goes on behind the scenes.

*

Username

  • Administrator
  • 17687
  • President of The Flat Earth Society
Re: Anybody here made their own programming language?
« Reply #129 on: March 20, 2023, 04:46:52 PM »
If you want to go another step further, you can implement a stack and have it deal with either postfix or prefix and you have the basics of a simple mathematical interpreter like maple. Chatgpt is great for tasks like reinventing the wheel.
The illusion is shattered if we ask what goes on behind the scenes.

*

Username

  • Administrator
  • 17687
  • President of The Flat Earth Society
Re: Anybody here made their own programming language?
« Reply #130 on: March 20, 2023, 04:49:17 PM »
Come to think of it, bungie used a very similar pattern for its scripting in the Myth series of games as well as probably Marathon. While they used a bytecode pattern, its not hard to imagine how to get from here to there if we were using c instead of python. As a child I recall implementing a turing machine in its scripting engine, and later recall working on the c code itself bringing it full circle.

However, don't take me wrong, I applaud your efforts and its a cool project.
« Last Edit: March 20, 2023, 04:55:22 PM by Username »
The illusion is shattered if we ask what goes on behind the scenes.

*

FlatAssembler

  • 672
  • Not a FE-er
Re: Anybody here made their own programming language?
« Reply #131 on: April 10, 2023, 08:48:28 AM »
Today, I have implemented the Routh-Hurwitz Stability Criterion in my programming language: https://flatassembler.github.io/hurwitz.html
Fan of Stephen Wolfram.
This is my parody of the conspiracy theorists:
https://www.theflatearthsociety.org/forum/index.php?topic=71184.0
This is my attempt to refute the Flat-Earth theory:

*

Wolvaccine

  • EXTRA SPICY MODE
  • 25833
Re: Anybody here made their own programming language?
« Reply #132 on: April 10, 2023, 08:52:45 AM »
Today, I have implemented the Routh-Hurwitz Stability Criterion in my programming language: <<spambot site removed>>

This post looks eerily similar to the spam bots plugging their stupid sites.

Quote from: sokarul
what website did you use to buy your wife? Did you choose Chinese over Russian because she can't open her eyes to see you?

What animal relates to your wife?

Know your place

*

FlatAssembler

  • 672
  • Not a FE-er
Re: Anybody here made their own programming language?
« Reply #133 on: April 10, 2023, 11:41:02 AM »
What do you think, what is the easiest way to implement the special cases of the Hurwitz algorithm, that is, when one or more elements in a row of a matrix are zero?
The core of my program is this:
Code: [Select]
Function popuni_matricu() Which Returns Integer16 Does
  Integer16 broj_stupaca :=
              (stupanj_polinoma + 1) / 2 + mod(stupanj_polinoma + 1, 2),
            broj_redaka := stupanj_polinoma + 1;
  Integer16 i := 0;
  //Popunimo matricu prvo not-a-numbersima...
  While i < broj_redaka Loop
    Integer16 j := 0;
    While j < broj_stupaca Loop
      matrica[f(i, j)] := 0. / 0.;
      j += 1;
    EndWhile
    i += 1;
  EndWhile
  //Zatim idemo primjeniti Hurwitzov algoritam...
  i := 0;
  While i < broj_redaka Loop
    Integer16 j := 0;
    While j < broj_stupaca Loop
      If i = 0 Then // Prvi redak
        matrica[f(i, j)] := polinom[j * 2];
      ElseIf i = 1 Then // Drugi redak
        matrica[f(i, j)] := (j * 2 + 1 < stupanj_polinoma + 1) ?
                            polinom[j * 2 + 1] :
                            0;
      Else // Ostali reci...
        If matrica[f(i - 1, 0)] = 0 Then
          //TODO: Implementirati što se radi u posebnim slučajevima...
          Return 0;
        EndIf
        matrica[f(i, j)] := (matrica[f(i - 1, 0)] *
                            (j + 1 < broj_stupaca ?
                             matrica[f(i - 2, j + 1)] : 0) -
                            (matrica[f(i - 2, 0)] *
                            (j + 1 < broj_stupaca ?
                             matrica[f(i - 1, j + 1)] : 0))) /
                            matrica[f(i - 1 , 0)];
      EndIf
      j += 1;
    EndWhile
    i += 1;
  EndWhile
  If matrica[f(broj_redaka - 1, 0)] = polinom[stupanj_polinoma] Then
    Return 1;
  EndIf
  Return 0;
EndFunction
What should be done at the place of TODO, instead of returning an error code? " class="bbc_link" target="_blank" rel="noopener noreferrer">Neso Academy video presents two ways of dealing with that, none of which seem easy to program.
Fan of Stephen Wolfram.
This is my parody of the conspiracy theorists:
https://www.theflatearthsociety.org/forum/index.php?topic=71184.0
This is my attempt to refute the Flat-Earth theory:

*

FlatAssembler

  • 672
  • Not a FE-er
Re: Anybody here made their own programming language?
« Reply #134 on: June 10, 2023, 01:23:58 PM »
Thanks to the StackExchange user kaya3, today, I discovered and fixed two bugs in my AEC-to-WebAssembly compiler (one in the semantic analyzer and one in the core of the compiler): https://github.com/FlatAssembler/AECforWebAssembly/issues/19
Before the fix, a program that attempts to use structures of two different types as the second and the third operand of the ternary conditional `?:` operator (which is never valid):
Code: [Select]
Structure First Consists Of
Nothing;
EndStructure

Structure Second Consists Of
Nothing;
EndStructure

Function main(Integer32 a, Integer32 b) Which Returns Nothing Does
InstantiateStructure First firstStructure;
InstantiateStructure Second secondStructure;
InstantiateStructure Second thirdStructure := (a > b) ? firstStructure : secondStructure;
EndFunction
Made my compiler crash with the following error message:
Code: [Select]
Running the tests...
All the tests passed in 4 milliseconds.
Reading the file "debug.aec"...
All characters read in 0 milliseconds.
Tokenizing the program...
Finished tokenizing the program in 0 milliseconds.
I have made a forum thread about how to speed up the tokenizer,
in case you are interested:
https://www.forum.hr/showthread.php?t=1243509
Parsing the program...
Finished parsing the program in 0 milliseconds.
Compiling the program...
Line 10, Column 29, Internal compiler error: Some part of the compiler attempted to compile an array with size less than 1, which doesn't make sense. Throwing an exception!
Internal compiler error: Uncaught exception in the compiler: St13runtime_error: Compiling an array of negative size!
If you have time, please report this to me on GitHub as an issue:
https://github.com/FlatAssembler/AECforWebAssembly/issues
Truly an absurd (not helpful at all) error message, right? It took me hours to figure out what is actually going on in my compiler (which is not very surprising, considering I wrote the core of it three years ago).
Fan of Stephen Wolfram.
This is my parody of the conspiracy theorists:
https://www.theflatearthsociety.org/forum/index.php?topic=71184.0
This is my attempt to refute the Flat-Earth theory: