Skip to content
← Back to Community
Making a Functional Programming Language with JS Part 1
Profile icon
AnthonyMouse

Hello! I’m @EitanAlperstein (also @AnthonyMouse) with a tutorial. Hope you like it, because I spent a lot of hard work on the language AND the tutorial. Feel free to share with others, and fork my lang, which I called, ”Expression”. Anyways, let’s get started!


I’ve searched online a million+2 times for “How to Make a Coding Language”, and even when I actually got results they were all “Lexer” and “Parser” and “Object Notation Tree” (no I made the last one up but you get my point, right?) They are important concepts, but what about the actual code for it? They were all *”Umm…I know all this interpreter stuff but I don’t have any code to give” so I decided to make my own tutorial.
__

Other cool tutorials

In spite of my little lecture (say that 3 times fast! :P) I did find a few good tutorials, some that I’m even basing on right now. So here’s a list:

Getting Started

Requirements

Not prerequisites, we need to use the function-require()-!
You should have Node installed, or, even better, make a NodeJS repl!
So let’s start requireing!

const fs = require('fs'), prompt = require("prompt-sync")()

We’ll need fs to read the file, and prompt for input commands and repl sessions (lol. repl). Also, while we’re on the variables topic…

let vars = {}

I made a variable, with the variables from our session. Great, next step!

Setting up the interpreter

I promise no more big words. Ok, I don’t promise but I’ll try not to.
Let’s just do a quick copy paste

function parse(string) { // Start with an object to hold the top-level fields let result = {}; let section = result; string.split(/\r?\n/).forEach(line => { let match; if (match = line.match(/^(\w+)=(.*)$/)) { section[match[1]] = match[2]; } else if (match = line.match(/^\[(.*)\]$/)) { section = result[match[1]] = {}; } else if (!/^\s*(;.*)?$/.test(line)) { throw new Error("Line '" + line + "' is not valid."); } }); return result; }

We don’t need the last few lines, so I deleted them.
So…why doesn’t this thing work? Well, we never read the file. So let’s add this at the end:

parse(fs.readFileSync(‘main.exp’, ‘utf-8’))

I know sync is probs a bad idea, but it runs much faster than you probably heard. If you have a better async version, shoot it in the comments. (I foresee the first comments is gonna be like “Eitan, you can do this instead of that” or “Eitan, there’s such a better way to do this”, or if you read this part, “lol”)
So far, your code should look like this:

const fs = require('fs'), prompt = require("prompt-sync")() let vars = {} function parse(string) { string.split(/\r?\n/).forEach(line => { let match; if (match = line.match(/^(\w+)=(.*)$/)) { section[match[1]] = match[2]; } else if (match = line.match(/^\[(.*)\]$/)) { section = result[match[1]] = {}; } else if (!/^\s*(;.*)?$/.test(line)) { throw new Error("Line '" + line + "' is not valid."); } }); return result; } parse(fs.readFileSync('main.exp', 'utf-8'))

(If that does not work check what your function is called :) )

We first need to decide on syntax. In all the other tutorials I was talking about, they would spend a page to decide about it. ONE LINE. Done.
print(‘Hello’);
Whoa. That was so hard. (I think you can hear my sarcasm, but this is a computer so that’s sarcastic)
Let’s start coding.
Delete everything except the forEach statement inside the function.
In the forEach, add this:

let lines, chars string.split(/\r?\n/).forEach(line=>{ let match lines++ chars = line.length if (match = line.match(/^print\([‘“]([\s\S]*)[‘“]\)/)) { process.stdout.write(match[1]) } else if (!/\/\/[\s\S]*/.test(line)) { throw new SyntaxError(“Syntax ” + line + “ is not valid. Check on “ + “main.exp” + “:” + lines + “:” + chars + “;”) } }

Why process.stdout? You’ll see…
Source:

const fs = require('fs'), prompt = require("prompt-sync") let vars = {} function parse(string) { let lines, chars lines = 0 chars = 0 string.split(/\r?\n/).forEach(line=>{ let match lines++ chars = line.length if (match = line.match(/^print\([‘“]([\s\S]*)[‘“]\)/)) { process.stdout.write(match[1]) } else if (!/\/\/[\s\S]*/.test(line)) { throw new SyntaxError("Syntax " + line + " is not valid. Check on " + "main.exp" + ":" + lines + ":" + chars + ";") } }) } parse(fs.readFileSync('main.exp', 'utf-8'))

OR
Repl.it - Expression1

Note

I am working on several projects at once. The next one may not be released that soon.

Voters
Profile icon
AnthonyMouse
Profile icon
EpicGamer007
Comments
hotnewtop
Profile icon
Battledash2

No semicolons. Hate it. Just kidding :)

If I'm being totally honest, there's no lexer or parser.... It's all regular expression :(

Profile icon
AnthonyMouse

Haha this was from my innocent days @Battledash2

Profile icon
Battledash2

Lolz
I remember making stuff like this.... Expecting to actually make a language... ah @AnthonyMouse

Profile icon
programmeruser

How is this creating a functional programming language? (sorry for necropost)

Profile icon
programmeruser

I know sync is probs a bad idea

Well, it's not such a bad idea if you're not creating a high performance application such as web servers, and you're just creating something like a terminal application.

Profile icon
AnthonyMouse
Profile icon
programmeruser

Isn't this more of a tutorial on regexes?

Profile icon
AnthonyMouse

Hmm… It does help a lot… also, are you stalking my posts? lol @programmeruser

Profile icon
programmeruser

@AnthonyMouse I'm not stalking your posts... what makes you think that?

Profile icon
AnthonyMouse
Profile icon
Wumi4

It's look kinda complex because of to how complexity the Regex rules is. I think parsing code token by token, line by line is a simpler and easier choice. But anyway, nice work! :)

Profile icon
AnthonyMouse
Profile icon
AnthonyMouse

And thank you. @Wumi4

Profile icon
EpicGamer007

ping me for part 2 plez?

Creating a programming lang is something im really interested in but IDK enough C++ or C so this is a great way for me to learn more node and do something I have been wanting to do!

Profile icon
EpicGamer007

Also ur attached repl does not work. there is a syntax error for some reason

Profile icon
AnthonyMouse

Ok, and I’ll check the syntax error. @EpicGamer007

Profile icon
programmeruser

@EpicGamer007 I can teach you how to make an actual one (that isn't regexp). Just invite me to a node repl

Profile icon
AnthonyMouse

Hmm, I’m curious. Could you invite me too? @EpicGamer007

Profile icon
EpicGamer007

@programmeruser sure can you invite me?

Profile icon
programmeruser
Profile icon
AnthonyMouse

can you invite me? @programmeruser

Profile icon
programmeruser