Skip to content

Releases: bitdotgames/BHL

v2.0.0-beta13

28 Dec 12:53
Compare
Choose a tag to compare
  • Using '..' prefix instead of '.' for global namespace symbols lookup
  • Native class and interface symbols are now explicitely setup lazily to avoid declaration order dependencies

v2.0.0-beta11

13 Dec 08:38
Compare
Choose a tag to compare

Warning: this release breaks BC with previous beta releases

  • Passing values stack more explicitly
  • Fixed casting to (int) which now internally uses ulong
  • Making VM.TryFindFuncAddr(..) public and adding VM.Start(..) variation which accepts FuncAddr
  • Adding line number to InitFrame opcode
  • Adding better async yield chain calls validation
  • Adding more universal binary operator overloads: now they are static methods
 var op = new FuncSymbolNative("+", FuncAttrib.Static, ts.T("Color"), 0,
      delegate(VM.Frame frm, ValStack stack, FuncArgsInfo args_info, ref BHS status)
      {
        var other = (Color)stack.PopRelease().obj;
        var self = (Color)stack.PopRelease().obj;

        var v = Val.NewObj(frm.vm, self + other, Types.Color);
        stack.Push(v);

        return null;
      },
      new FuncArgSymbol("self", ts.T("Color")),
      new FuncArgSymbol("other", ts.T("Color"))
   );
cl.Define(op);

v2.0.0-beta1

23 Nov 13:36
Compare
Choose a tag to compare
v2.0.0-beta1 Pre-release
Pre-release

Warning: this release breaks BC with previous alpha releases

Introducing new async/yield semantics

  • Now it's required to mark coroutine functions which may execute longer than one frame with async keyword.
  • Any function using yield statements is considered a coroutine.
  • Coroutines must be called using yield statement.
  • yield calls are not allowed by compiler inside of defer {..} blocks.
  • Pointer to async function is considered compatible with pointer with the same signature to non-async function. But not vice versa.

Quick async/yield example:


async func bool GetBool() {
  yield while(IsReady())
  yield()                  //yields one tick as before
  return yield CalcBool()  //CalcBool() must be an async function as well
}

Async pointers compatibility. The following code works just fine since non async functions are a superset over async ones.

async func int () p = func int () { return 10 } 
p()

However this is a compile time error: non async pointer can't be assigned an async function:

func int () p = async func int () { 
  yield()
  return 10 
} 

Unifying function attributes syntax

All function attributes (async, virtual, static, etc) must come before func keyword. For example:


class Bar {
  async virtual func int foo() { ..} 
 }

The following code is now a compile time error:

class Bar {
  async func virtual int foo() { ..} 
 }

Calling functions in a global namespace is now forbidden

The following code is a compile time error:

namespace foo {
   Config conf = GetConfig("hey")
}

It rather should be:

namespace foo {
   Config _conf
   
   func Config conf() {
     if(_conf == null) {
      _conf = GetConfig("hey")
     }
     return _conf;
   }
}

Added support for simplified strings concatenation

string foo = "world "
foo += "hello\n" 

v2.0.0-alpha78

18 Nov 12:01
Compare
Choose a tag to compare
v2.0.0-alpha78 Pre-release
Pre-release

Implicit variable type declaration with 'var' keyword

func string test() {
   var a = "Hello World"
   return a
 }

Convenient nested namespaces declarations

namespace foo.bar {
 …
}

fail() built-in function removed

fail() function removed until we have a better understanding about handling of failures in version 2.0. It was not widely used and didn't allow any recovering in userland code. Once there's a more robust and reliable solution it will be introduced once again.

v2.0.0-alpha67

30 Aug 13:11
Compare
Choose a tag to compare
v2.0.0-alpha67 Pre-release
Pre-release
  • Better protection against stack interleaving in paral branches
  • Better compile time errors reporting
  • Better handling of return keyword parsing ambiguities

v2.0.0-alpha60

19 Aug 12:47
Compare
Choose a tag to compare
v2.0.0-alpha60 Pre-release
Pre-release

Maps foreach and json-alike initialization support

foreach(string k,int v in m) {
  …
}
[string]int m = {“Bob” : 42, “Sally” : 69}  

Nested classes

     class Bar {
        class Foo {
           int f
           func int getF() {
             return this.f
           }
        }
    }
     
    Bar.Foo foo = {f: 1}
    foo.getF()

Nested class interfaces

     class Bar {
        interface IFoo {
          func int foo()
        }
      }

      class Foo : Bar.IFoo {
        func int foo() {
          return 1
        }
      }   

Nested class enums

     class Bar {
         enum E {
           E1 = 1
           E2 = 2
         }
         func E getEnum() {
           return E.E2
         }
      }

      Bar bar = {}
      int what = (int)Bar.E.E1 + (int)bar.getEnum() 

Static class fields and methods

     class Bar {
        static int bar
        func static int foo() {
          return 42
        }
      }

     Bar.bar = 14
     int sum = Bar.bar + Bar.foo()

Variadic function arguments

   func int sum(...[]int ns) {
      int s = 0
      foreach(int n in ns) {
        s += n
      }
      return s
    }

  sum(1, 2, 3)
  sum(...[1, 2, 3])

v2.0.0-alpha39

20 Jul 10:46
Compare
Choose a tag to compare
v2.0.0-alpha39 Pre-release
Pre-release

Basic polymorphic methods support

class Foo {
  int a
  int b
  func virtual int getA() {
     return this.a
  }
  func int getB() {
    return this.b
  }
}

class Bar : Foo {
   int new_a
   func override int getA() {
     return this.new_a
   }
}

Better support for local variables scopes

The following code was impossible before resulting in "already declared symbol i" error:

   {
     int i = 1
     i = i + 1
     trace((string)i)
   }
   {
     string i
     i = ""foo""
     trace((string)i)
   }

The following code is now possible as well (variable i is declared twice in each loop condition section):

   for(int i=0;i<5;i++) {
    …
   }
  
   for(int i=0;i<10;i++) {
    …
   }

Initial implementation of maps

[string]int m = {"wow" : 42}
m["hey"] = 14

if(!m.Contains("bar")) {
  m["bar"] = 4
}
bool ok,int v = m.TryGet("bar")
if(ok) {
 ...
} 

foreach(string k, int v in m) {
 ...
}

m.Remove("hey")
m.Clear()

Arbitrary order of symbols declarations

For example the following code was not valid before resulting in "symbol Bar not found" error:

interface IBar {
   func Bar circularDependency()
}

class Bar : IBar {
   func Bar circularDependency() {
     return this
   }
}

Draft std of library implementation

import "std"

func main() {
  std.io.WriteLine("Hello World!")
}

v2.0.0-alpha12

06 May 14:47
Compare
Choose a tag to compare
v2.0.0-alpha12 Pre-release
Pre-release
  • More consistent addressing of enum items: using . instead of ::
enum Items {
   BAR = 1
   FOO = 2
}

func Items test() {
  return Items.BAR
}
  • Fixing namespace symbols lookup from inside a lambda

v2.0.0-alpha11

05 May 15:24
Compare
Choose a tag to compare
v2.0.0-alpha11 Pre-release
Pre-release
  • Adding initial namespaces support which led to major internal type system overhaul
  • Namespace symbol aliases not available yet

Conceptually namespaces are quite similar to the implementation found in C#: one is free to declare and nest namespaces anywhere in the code. It's possible to span namespaces across multiple files.

File: std/io.bhl

namespace std {
namespace io {
  func int WriteLine(string line) {
    …
  }
}
}

File: main.bhl

import "std/io"

func main() {
  std.io.WriteLine("Hello World!")
}

In case you need to explicitly lookup a symbol in the global namespace you have to prefix it with . (dot), for example:

namespace foo {
   func yield() {
     …
   }

   func test() {
      yield()  // will lookup foo.yield()
      .yield() // will lookup built-in global yield()
   }
}  

v2.0.0-alpha10

08 Apr 10:25
Compare
Choose a tag to compare
v2.0.0-alpha10 Pre-release
Pre-release
  • Adding basic support for interfaces
  • Adding support for is T expression
  • Adding support for as T expression
  • Adding support for typeof(T) which returns type as a value of type Type
  • Adding built-in func Type type(any o)
  • Changing foreach syntax, making it more C# more alike: foreach(arr as a) -> foreach(a in arr)
  • Internal clear distinction between Int and Float types for Val: Val.SetNum() -> Val.SetInt(..) and Val.SetFlt(..)
  • LSP internal improvements
  • VM internal optimisations