Skip to content

Introducing the world's first DreamBerd interpreter

Compare
Choose a tag to compare
@TodePond TodePond released this 23 Feb 10:43
· 162 commits to main since this release
2d2f361

Over the years, many people have tried and failed to implement DreamBerd. No one has been able to do it...

Until today!

Introducing Vivaan Singhvi, a highschool student who has now created the world's first mostly-functional Dreamberd interpreter. This is extremely impressive, as it's a task that many experienced programmers have struggled with.

As promised, I have now donated Β£99 to a charity of Vivaan's choice, Second Harvest Food Bank.

The money will pay for approximately 375 meals for children and families experiencing hunger. I now invite you to donate as well! If you do so, please let me know on social media by tagging @TodePond. I'll give you a boost!

And now I want to show you how well the interpreter fared up with DreamBerd. Here's the analysis.

Implementation report

Exclamation marks

πŸ† Complete pass

All exclamation mark syntax worked well.
Notably, the debug information I got from my question mark was clear and helpful.

print("Hello world")!
print("Hello world")!!!
print("Hello world")?
if (;false) {
   print("Hello world")!
}

Console:

Hello world
Hello world
Hello world

exclamation-marks/bold.db, line 3

  print("Hello world")?
  ^^^^^
Expression evaluates to value undefined.

Hello world

Const const

πŸ† Complete pass

const const name = "Luke"!
print(name)!
Luke

Const var

πŸ… Lenient pass

The pop method from the example didn't work, but constant variables worked as expected with other methods.

const var name = "Lu"!
name.push("ke")!
print(name)!
Luke

Var const

πŸ† Complete pass

var const name = "Luke"!
name = "Lu"!
print(name)!
Lu

Var var

πŸ… Lenient pass

Similar to above, the pop method didn't work, but push worked fine.

var var name = "Luke"!
name = "Lu"!
name.push("ke")!
print(name)!
Luke

Const const const

πŸ’° Untested

For the first bounty, a global "const 3" server is not needed, so I didn't test this.

However, the interpreter does state that it supports const 3!

Unicode naming

πŸ… Buggy pass

The 1️⃣ emoji didn't work, but most other emojis do work.
Notably, the True value was correctly interpreted as a string!

const const letter = 'A'!
var const πŸ‘ = True!
var var 🐦 = 1!

print(letter)!
print(πŸ‘)!
print(🐦)!
A
True
1

Number naming

πŸ† Complete pass

I had to add in some extra whitespace because the interpreter partially implements the parentheses features of DreamBerd, which are not required or tested as part of this first bounty.

const const 5 = 4!
print( 2 + 2 == 5 )!
true

Negative one index arrays

πŸ† Complete pass

const const scores = [3, 2, 5]!
print(scores[-1])!
print(scores[0])!
print(scores[1])!
3
2
5

Float array indexing

πŸ’₯ So close!

This should print [3, 2, 4, 5] instead.

const var scores = [3, 2, 5]!
scores[0.5] = 4!
print(scores)!
[3, 4, 2, 5]

When

πŸ† Complete pass

This was one of the first features I tried. Amazing!

var var health = 10!
when (health == 0) {
   print("You lose")!
}

print("You got hit")!
health = 0!
You got hit
You lose

Line-based lifetimes

πŸ† Complete pass

const const name<2> = "Luke"!
print(name)!
Luke
Error

Time-based lifetimes

πŸ’₯ Failure

This caused an error.

const const name<20s> = "Luke"!
print(name)!

Infinity-based lifetimes

πŸ† Complete pass

I genuinely can't believe this worked. I ran one program that set an infinite-lifetime constant...

const const foreverName<Infinity> = "Luke"!

Then I ran another program to read it and print it out.

print(foreverName)!
Luke

Loops

πŸ† Complete pass

There are no loops.

Booleans

πŸ… Lenient pass

The interpreter is based off a slightly older version of DreamBerd that uses the after keyword instead of addEventListener. I didn't test those older features, but I tested that you can use the maybe boolean value still. The interpreter seems to treat maybe like a string, which is fine I guess.

const const isTuesday = maybe!
print(isTuesday)!
maybe

Significant whitespace

πŸ† Complete pass

Amazing. Love it.

print( 1 + 2*3 )!
print( 1+2 * 3 )!
7
9

Powers

πŸ† Complete pass

print(1^1)!
print(2^3)!
1
8

Number names

πŸ† Complete pass

Incredible.

print( one + two )!
print( thirteen + two )!
3
15

Indentation

πŸ… Lenient pass

The interpreter allows indents of multiples of 3, which is standard practice among DreamBerd implementations. However, it also allows the use of the tabs (in place of two spaces), which is strictly forbidden. I will allow it this once.

function main() => {
   print("DreamBerd is the future")!
}

main()!
DreamBerd is the future

Negative indent:

   function main() => {
print("DreamBerd is the future")!
   }

   main()!
DreamBerd is the future

Loose check

πŸ† Complete pass

print( 3.14 == "3.14" )!
true

Precise check

πŸ† Complete pass

print( 3.14 === "3.14" )!
false

Identity check

πŸ† Complete pass

const const pi = 3.14!
print( pi ==== pi )!
print( 3.14 ==== pi )!
true
false

Lexical check

πŸ’₯ Failure

The interpreter should return true for lexical checks when using four equals signs.

print( 3.14 ==== 3.14 )!
false

Imprecise check

πŸ† Complete pass

print( 3 = 3.14 )!
true 

Functions

πŸ† Complete pass

function add (a, b) => a + b!
func multiply (a, b) => a * b!
fun subtract (a, b) => a - b!
fn divide (a, b) => a / b!
functi power (a, b) => a ^ b!
union inverse (a) => 1/a!

print( add(3, 2) )!
print( multiply(3, 2) )!
print( subtract(3, 2) )!
print( divide(3, 2) )!
print( power(3, 2) )!
print( inverse(3) )!
5
6
1
1.5
9
0.3333333333333333

Dividing by zero

πŸ† Complete pass

print(3/0)!
undefined

String literals

πŸ† Complete pass

Zero-quote strings are not required for this bounty, but the interpreter still supports it in some cases. ie: It works for one-word zero-quote strings.

const const single = 'Lu'!
const const double = "Luke"!
const const triple = '''Lu'''!
const const mixed = "'Lu'"!
const const octuple = """"Luke""""!
const const none = Luke!

print(single)!
print(double)!
print(triple)!
print(mixed)!
print(octuple)!
print(none)!
Lu
Luke
Lu
Lu
Luke
Luke

String interpolation

πŸ… Lenient pass

String interpolation worked, though it incorrectly thought I was in america.

const const name = "world"!
print( "Hello ${name}!" )!
print("Hello Β£{name}!")!
print("Hello Β₯{name}!")!
print("Hello {name}€!")!
Hello world!
Hello Β£{name}!
Hello Β₯{name}!
Hello {name}€!

Types

πŸ† Complete success

Types get stripped and ignored.

const var age: Int = 28!
const var score: Int9 = 10!

print(age)!
print(score)!
28
10

Regular expression types

πŸ… Lenient pass

Many regular expressions work, but the long crazy one in the example causes an error.

const const name: /[a-zA-Z]+/ = "Luke"!
print name!
Luke

Previous

πŸ… Lenient pass

It didn't work with the ++ operator, but it worked when I wrote it out like this.

var var score = 5!
score = score + 1!
print(score)!
print(previous score)!
6
5

Next

πŸ’° Untested

I couldn't figure out how to test this one, because I noticed that the DreamBerd example in the docs used old features that aren't supported anymore.

Current

πŸ† Complete pass

var var score = 5!
print(current score)!
5

File structure

πŸ† Complete pass

const const score = 5!
print(score)!

=====================

const const score = 3!
print(score)!

File names

πŸ† Complete pass

======= add.db =======
function add(a, b) => {
   return a + b!
}

print( add(1, 2) )!
3

Exporting

πŸ† Complete pass

===== add.db ==
function add(a, b) => {
   return a + b!
}

export add to "main.db"!

===== main.db ==
import add!
print( add(3, 2) )!

Single instance classes

πŸ† Complete pass

class Player {
   const var health = 10!
}

const var player1 = new Player()!
const var player2 = new Player()!
Error: Already made instance of the class "Token(TokenType.NAME, 'Player')".

Factory classes

πŸ† Complete pass

var var count = 0!

class PlayerMaker {
   function makePlayer() => {
      count = count + 1!
      class Player {
         const var health = 10!
         const var id = count!
      }
      const const player = new Player()!
      return player!
   }
}

const const playerMaker = new PlayerMaker()!
const var player1 = playerMaker.makePlayer()!
const var player2 = playerMaker.makePlayer()!

print(player1.id)!
print(player2.id)!
1
2

Time

πŸ’₯ Failure

This caused an error.

print( Date.now() )!

Delete numbers

πŸ† Complete pass

Ridiculous, amazing.

delete 3!
print( 2 + 1 )!
Error: The value 3 has been deleted.

Delete class

πŸ† Complete pass

delete class!
class Player {}
Error

Delete delete

πŸ† Complete pass

delete delete!
delete 3!
Error

Order overloading

πŸ† Complete pass

const const name = "Luke"!
const const name = "Lu"!
print(name)!
Lu

Exclamation mark overloading

πŸ’₯ Close one

This worked for the simple case.

const const name = "Lu"!!
const const name = "Luke"!
print(name)!
Luke

But it didn't work for a more complex example.

const const name = "Lu"!!
const const name = "Luke"!
const const name = "Lu or Luke"!!!
print(name)!
Lu

Inverted exclamation mark

πŸ† Complete pass

const const name = "Lu"!
const const name = "Luke"Β‘
print(name)!
Lu

Reversing

πŸ† Complete pass

Oh my god it works!!!!!!!!

const const message = "Hello"!
print(message)!
const const message = "world"!
reverse!
Hello
world

Class names

πŸ† Complete pass

className Player {
   const var health = 10!
}

const const player = new Player()!
print(player.health)!
10

DBX

πŸ’° Untested

Not required as part of this bounty.

Semantic naming

πŸ† Complete pass

This doesn't require any implementation. Semantic naming melts away as intended.

const const sName = "Lu"!
const const iAge = 29!
const const bHappy = true!
const const g_fScore = 4.5!

print(sName)!
print(iAge)!
print(bHappy)!
print(g_fScore)!
Lu
29
true
4.5

Asynchronous functions

πŸ† Complete pass

Really pleased to see this one work!

async funct count() => {
   print(1)!
   print(3)!
}

count()!
print(2)!
1
2
3

Noop

πŸ† Complete pass

As mentioned earlier, zero-quoted strings work, like noop.

async func count() => {
   print(1)!
   noop!
   print(4)!
}

count()!
print(2)!
print(3)!
1
2
3
4

Signals

πŸ† Complete pass

const var score = use(0)!

print(score())!
score(9)!
print(score())!
0
9

Destructuring signals

πŸ’₯ Failure

This causes an error.

const var [getScore, setScore] = use(0)!

setScore(9)!
getScore()?

AI

πŸ’° Untested

Another day.

Parentheses

πŸ’° Valient effort

Arbitrary parentheses were not part of this bounty, but the interpreter does a great job at them anyway, which is incredible! Significant whitespace is used to indicate grouping of arguments and operations.

func add(a, b) => a + b!

const const a = add(3, 2)!
const const b = add 3, 2!
const const c = (add (3, 2))!
const const d = add)3, 2(!

print(a)!
print(b)!
print(c)!
print(d)!
5
5
5
5

The interpreter errors with more advanced cases, which is understandable.

func add(a, b) => a + b!

const const a = (add (3, (add (5, 6))))!
const const b = (add (3, (add (5, 6)!

print(a)!
print(b)!

Comments

πŸ’₯ Failure

Comments aren't explicitly listed in the docs, but they appear in many examples. The following example errors.

// Comment

However, you can comments as strings if you want.

Comment!
"This is a comment"!

Conclusion

This is a remarkable effort by Vivaan, and it puts DreamBerd into a mostly-usable state. I was more than happy to pay the bounty to Second Harvest Food Bank, and I hope you consider joining me.

In the coming weeks, I'll introduce some more charity bounties, so keep an eye out.

Many thanks,
Lots of love,
Yours sincerely,

Lu (or Luke) (either's fine)
xxxxxxxx