Stack based languages and local variables...

Programming, for all ages and all languages.
Post Reply
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Stack based languages and local variables...

Post by Alboin »

I'm attempting to implement a small, portable, compiled stack based language for my osdev endeavors. I am currently in the early steps in writing my compiler(In perl, because I want portability, and I don't want to play with strings in C.) However, I've run into a problem....How does one implement local variables in a stack based programming language? I've read that local variables are implemented using the stack, but if my language uses the stack for everything, I'm not thinking that will work.....Any ideas?

Thanks!
C8H10N4O2 | #446691 | Trust the nodes.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

A compiler written in Perl? That'll be a first.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

ehird wrote:A compiler written in Perl? That'll be a first.
Really? It makes everything so easy. though....

I now have a compiler that will start to assemble things...but....it seems as if there is too much pushing....For instance, when I do something like:

Code: Select all

32 $x @add
I get:

Code: Select all

push 32
push word [x]
pop eax
pop ebx
add eax, ebx
push eax
Does anyone know a smaller way to compile a stack based language to assembly? Or should I just convert my language to an imperative one? (Shouldn't be too hard..)
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
Alboin
Member
Member
Posts: 1466
Joined: Thu Jan 04, 2007 3:29 pm
Location: Noricum and Pannonia

Post by Alboin »

Well fine! Don't replay to my topic! :) (Just kidding)

I've found that stack based languages are not easy to compile efficiently, so I have gone and made an imperative stack type language. I plan for it to be specifically for osdev and cross platform assembly type stuff, where you don't feel like playing with C's noisy compiler. For example:

Code: Select all

~main {
     12 (cv)
     23452 $cv:4 =
}
Now, this directly translates to:

Code: Select all

main:
	mov dword [cv], 2203409

cv: db 0,0,0,0,0,0,0,0,0,0
Moreover, I have a simple directive system in a slightly working process, so:

Code: Select all

~main {
       1 (char)
       65 $char =
       
       %asm {
               mov eax, 32
        }
}
translates to:

Code: Select all

main:
	mov byte [char], 65
        mov eax, 32		

char: db 0
I designed the syntax to be extremely compiler friendly. Currently, it all fits in 3.3kb of Perl code, using regular expressions as if prohibition started tomorrow.

The question is: what would you want if you were designing a language for osdev? Any suggestions?

Thanks.
C8H10N4O2 | #446691 | Trust the nodes.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

The whole idea of stack-based languages is to do away with the idea of local variables, at least in the sense of local-variables with names, instead using explicit stack manipulation to do the same.

Consider the following example in Lisp:

Code: Select all

(let ((x 2))
  (+ x x))
That binds a local variable x to the value 2, and then adds two x's together.
In a stack based language you'd do the same thing as something like:

Code: Select all

  2 dup +
In other words: push the value 2, then duplicate the top of stack, and then replace the 2 topmost elements with their sum.

I think the easiest way to compile a stack-based language efficiently (in the sense of actually doing more complicated optimizations than just peepholing certain combinations of words) would be to convert the code back to something functional like Scheme, A-normalize the result, and then compile it. You'll probably have to do that globally to the whole program to get much out of it but..

On the other hand, if you don't want to optimize (other than said peepholing) then compiling a stack based language basicly consists of writing assembly version of all the primitive words (as Forth calls them) and reading the source, patching sequences of the primitive words and calls to non-primitive words (=other sequences of primitive and non-primitive words). Doing this isn't very hard.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
Post Reply