I’ve now implemented the .size operator for arrays
Tag: Scripting
Arrays Completed 75%
Arrays can now be declared separately from it’s definition. So
1 2 |
int[] vals; vals = {23,24,25}; |
will now work.
I’ve also added two new operators; “array push front”, which looks like
-> , and “array push back” which looks like
<- . The idea is that it’s pointing from the left to the left-most element, meaning push front and the alternative pointing from the right to the right-most element.
Next; because arrays are now effectively dynamically sized, I need some inherent way to find the size of an array. Like a .size member or something…
Arrays Completed 50%
I’ve now finished implementing arrays in my scripting language. For now, they’re not dynamically sized, and they need all their arguments when first created.
I.e. you need to write:
1 |
int[] anArray = {24,252,-24}; |
You can’t write
1 2 |
int[] anArray; anArray = {24,252,-24}; |
You can otherwise access array elements and update them as necessary. All regular automatic type conversion is handled. So:
1 |
int[] anArray = {"2949",234,52}; |
Will work. However, it does it a bit of a round-about way. The first element in an array value, everything between the { and } is used to determine the type of the array. In the above case it’s a string array.
Then, each subsequent element is type-converted to this type. So this becomes an array of strings.
Then the assignment of a string array value to an int array variable will cause a conversion from a string array to an int array.
If the first element was an int and not a string, only the first conversion takes place.
But, this allows me to keep the any-type to any-type conversion I wanted.
Interpreter Works
The first go at writing an interpreter for my compiled opcodes is working.
Great result. Now I basically have a working scripting engine, I just need to polish up the code and a few little bugs here and there (“-1” is read as “negative one” or “minus one”).
Scripting Language Updates
I’ve managed to put together a scripting language compiler that has the following features:
- Native data types: bool, string, char, int + float (I need to add vector types)
- C-like syntax
- Functions
- Automatic POD casting. I.e., every data type can be casted to another. This will be true even when I add classes or structs, not sure how…
- Ability to call “Engine” functions. I.e., you seed the Compiler with possible function calls that can be made of the platform
The compiler converts something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int AddAndPow(int a, int b); int main() { int i = engine.RandomNum(25235,1,"234093"); int j = engine.RandomNum(598498,1,10); i = AddAndPow(i,j); } int AddAndPow(int a, int b) { return (a + b); } |
Into:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
DATA 0 "234093" EDAT STRT 3 PUSH $0 CAST int PUSH #1 PUSH #25235 ENGE RandomNum STOR 4 PUSH #10 PUSH #1 PUSH #598498 ENGE RandomNum STOR 5 PUSH 5 PUSH 4 JUMP 0 STOR 4 ENDL 3 STRT 0 STOR 1 STOR 2 PUSH 1 PUSH 2 ADD RTRN ENDL 0 |
Which should be very simple for a Virtual Machine to run through and execute. You can see that no optimization has taken place; I’ll probably think about doing that after getting it to actually run.
Lexer
I’ve just completed a Lexer in order to produce a stream of tokens for the Parser.
There’s some parts of the Dragon Book which I don’t really understand the reasoning. Such as the Lexer adding info to the Symbol Table… why would it do that? It’s the Parsers job to build a syntax-tree, that seems like the correct place to add symbols. The Lexer is complicated enough just producing a stream of tokens.