#145689 - keldon - Tue Nov 20, 2007 2:41 pm
I'm looking for approaches to creating extremely simple scripting languages capable of at least if/else constructs and [maybe] for/while loops.
On top of this I would like to make it possible to write something of the following nature:
Code: |
if (cond)
begin
if (cond)
some_instruction ()
end
else if (cond)
begin
some_instruction ()
end
else
begin
end |
I have a [general] approach already written down (as a design, not code), which I started writing at about 6am this morning; but maybe someone has already written relevant accounts of their own findings.
On another note I just noticed that ...
Code: |
if (cond)
some_instruction ()
else if (cond)
some_instruction ()
else if (cond)
some_instruction ()
else if (cond)
some_instruction ()
else if (cond)
some_instruction () |
... is technically treated as ...
Code: |
if (cond)
{
some_instruction ()
}
else
{
if (cond)
{
some_instruction ()
}
else
{
if (cond)
{
some_instruction ()
}
else
{
if (cond)
{
some_instruction ()
}
else
{
if (cond)
{
some_instruction ()
}
}
}
}
} |
#145694 - ps2aich - Tue Nov 20, 2007 5:09 pm
I would recommend the Interpreter pattern, or very similar, the Visitor pattern on some own very small syntax tree.
Main problem will be to create a simple parser for your syntax that creates the Syntax tree, since on larger systems (e.g. PC) you can simply use an parser generator for this purpose (and don't bother about memory and speed requirements).
#145709 - sajiimori - Tue Nov 20, 2007 8:15 pm
If you don't need to write code directly on the DS, definitely compile to bytecode on your PC! It greatly simplifies the interpreter.
If this is your first language, I'd suggest hand-writing a recursive descent parser. It's pretty fun, and not too hard.
#145724 - keldon - Wed Nov 21, 2007 12:13 am
Thanks, well I've printed out plenty on the topics you've both given and I'll give them a look in the morning.
#145876 - keldon - Sat Nov 24, 2007 2:27 pm
Ok, my next main task is garbage collection now that I've cracked lexing as I think it makes scripting 1 000 times easier when you don't have to maintain references - the VM & compiler is not a problem to make.
#145883 - Ant6n - Sat Nov 24, 2007 9:09 pm
you should take a compilers course ;)
http://www.sable.mcgill.ca/~cpicke/520/#WEEKBYWEEK
week11 grabrage collection
#145886 - keldon - Sat Nov 24, 2007 9:33 pm
Ok, I'm downloading every slide! Don't really have time to take a course though (well not any I've seen), but I do have a big 1 000 page book on scripting from work that I am now half way though! I'm quite confident in creating garbage collection as I've read some IBM and Sun information on it, plus my personal need for it is not sophisticated at all. Not even for in game logic!
Thanks for the link, it will come in handy and give me cues on what books to read. Having said that, I could introduce scripting at quite a late date; or at least the sophisticated parts.
Well I'll follow that compilers course from week one once my bandwidth gets its act together; keep the help coming ^_^
#145968 - naleksiev - Mon Nov 26, 2007 6:48 pm
I'm aways using LISP like syntax for my scripts. I found it very easy to implement parser for it.
With such simple syntax you can easily compile it on the GBA/DS
#145969 - Kyoufu Kawa - Mon Nov 26, 2007 8:20 pm
I like Pok?mon-style sequential scripts. They're comfy and easy to extend.
#145971 - keldon - Mon Nov 26, 2007 10:41 pm
Hmm, LISP looks interesting, the way it operates is clever! I'm still thinking about garbage collection, I mean I'm not using it for in game logic, or where speed is important. It's basically for the GUI, I thought it would be fun to treat screens like HTML pages. So I've been experimenting with it - part for R&D at work, part for my web site, and part for fun.
Well at work I'm working on the PC, so memory is so _not_a_ problem for what I'm doing. I'm still thinking about garbage collection, how much could I script without it? The book I'm reading chooses to have all variables either static or on the stack with no allocation or references, therefore eliminating the need - having obvious limitations.
And thanks again for that link Ant6n!
#145973 - sajiimori - Mon Nov 26, 2007 11:32 pm
You can do a lot with just statics and locals. In fact, you can do everything with just statics and locals, since dynamic allocation can be implemented in terms of statics! (Think about how malloc and free must be implemented.)
You can support references to statics without risking dangling pointers, but references to locals are risky without garbage collection.
You can even support safe references to locals without garbage collection, although there are caveats. One method is to use dynamic scoping rather than lexical scoping.
Dynamic scoping is where there's a master table of all variable names and their associated values. Defining a local variable named X causes the old value of X to be backed up and the new value to overwrite it temporarily. When the local variable goes out of scope, the old value is restored.
(An alternative implementation of the same idea is to put local variables on a stack as usual, but keep auxiliary information on the stack that will allow a runtime algorithm to search it for the innermost variable named X.)
In this scenario, you can represent a reference as a string containing the name of the referred variable, although this potentially causes bad interaction between separate bodies of code that each create references to unrelated variables named X.
Much of the problem is resolved if you use unique symbols instead of strings. There are a finite number of local variable declarations in a program, and each one can be given a unique identifier (such as the in-memory address of the opcode declaring the variable, which is necessarily unique). There's still a potential problem when there can be more than one instance of a particular lexical variable on the stack at once, e.g. for recursive functions.
Whether using strings or unique identifiers, you also have to deal with the possibility that dereferencing will fail because there might not be a matching variable in scope. In these situations, you can either halt with an error, or return a special "null" value.