Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
A programming language written in naalaa
#21
Thumbs Up 
Wherever there's a forum, Aurel and Tomaaz will be there to argue Smile  I've been missing it though, so keep it up!
Reply
#22
Hi Marcus
I don't want to bothering you but something is not clear to me in
your PROLAN

inside procedure / function

 Signed factor.

procedure SignedFactor()
    if nextType = CHARACTER
        if nextAsc = CHR_PLUS
            ' Not quite sure here ...
            _GetNext
            _Factor

Why you not sure with calling
GetNext   or with  Factor ?
and i don't get it why you have SignedFactor and  just Factor ?
i have made recursive descent like this in 3 functions
look in this as pseudo code and what you think about that option?


'fn expression -----------------------------------------------

function Expression() as Float
float res
if tokType = tNUM OR tokType = tVAR  'num or numeric variable
    if nextTokenType = tPLUS OR nextTokenType = tMINUS
        if tPLUS '(+)
            GetToken() ' get token from token list/array
            res = token + Term()
        elseif tMINUS '(-)
            GetToken()
            res = token - Term()
        end if
    end if
end if
return res
end function

'term -------------------------------------------------------
function Term() as Float
float res
res = Factor()
if nextTokenType = tMULTI OR nextTokenType = tDIVIDE
    if tMULTI '(*)
        GetToken()
        res = res * Factor()
    elseif tDIVIDE '(/)
        GetToken()
        res = res / Factor()
    end if
end if
return res
end function

'factor -----------------------------------------------------
function Factor() as Float
float res
if tokType = tNUM
    return GetNum(token)
end if

if tokType = tVAR
    return GetVar(token)
end if

if tokType = tLParen '(
Match("(")
res = Expression()
Match(")")
end if
'else?
return res ' from func->Expression()
end function
Reply
#23
Not quite sure about the naalaa version of prolan. It was a mess. Have a look at the C version instead (https://naalaa.com/jail/). Probably it looks even worse, haha Smile  I'm no good at compiler construction or the theories behind it, so I probably make many things in stupid ways Big Grin

I've actually had some good use of jail while helping my woman write scripts that needed to process files recursively and such. Could never have used naalaa for that, and in C (her preferred language besides assembler) it would have been a complete mess Smile
Reply
#24
Yo Marcus

Just to let you know...
you dont need two factor routines than just one is enough 
no matter what you use directly -tokens or bytcode.
i do it in my new freak-show micro(A) interpreter like this:

Code:
'-----------------------------------------------------
sub gettok()
tc++
token = tokList[tc]
'test
if tokList[tc+1] <> "" then return
end sub
'----------------------------------------------------
sub expr() as float
float v
If token = "-"
v = -(term())
else
v = term()
end if

while token = "+" or token = "-"
if token = "+": gettok() : v = v + term(): end if
if token = "-": gettok() : v = v - term(): end if
wend

return v
end sub
'---------------------------------------------------
sub term() as float
float v
v = factor()

while token = "*" or token = "/"
if token = "*": gettok() : v = v * factor(): end if
if token = "/": gettok() : v = v / factor(): end if
wend

return v
end sub
'-------------------------------------------------------

sub factor() as float
float v
if asc(token)>47  and asc(token)<58 'nums
v = val(token)
'print str(v)+ " factor"
gettok()
end if

if asc(token)=40 and asc(token)<>41 'match (...)
gettok() : v = expr() : gettok()
end if


return v
end sub

'execute-----------------------------------------------------
sub exec
gettok()'start
float res = expr()
print "RESULT=" + str(res)
end sub

So, as you can see only three functions for expression evaluator.
By the way, your NaaLaa version of Prolan is very clear and good....  Smile
all best !
Reply
#25
(05-09-2019, 06:40 PM)Aurel Wrote: Yo Marcus

Just to let you know...
you dont need two factor routines than just one is enough 
no matter what you use directly -tokens or bytcode.
i do it in my new freak-show micro(A) interpreter like this:

Code:
'-----------------------------------------------------
sub gettok()
tc++
token = tokList[tc]
'test
if tokList[tc+1] <> "" then return
end sub
'----------------------------------------------------
sub expr() as float
float v
If token = "-"
v = -(term())
else
v = term()
end if

while token = "+" or token = "-"
if token = "+": gettok() : v = v + term(): end if
if token = "-": gettok() : v = v - term(): end if
wend

return v
end sub
'---------------------------------------------------
sub term() as float
float v
v = factor()

while token = "*" or token = "/"
if token = "*": gettok() : v = v * factor(): end if
if token = "/": gettok() : v = v / factor(): end if
wend

return v
end sub
'-------------------------------------------------------

sub factor() as float
float v
if asc(token)>47  and asc(token)<58 'nums
v = val(token)
'print str(v)+ " factor"
gettok()
end if

if asc(token)=40 and asc(token)<>41 'match (...)
gettok() : v = expr() : gettok()
end if


return v
end sub

'execute-----------------------------------------------------
sub exec
gettok()'start
float res = expr()
print "RESULT=" + str(res)
end sub

So, as you can see only three functions for expression evaluator.
By the way, your NaaLaa version of Prolan is very clear and good....  Smile
all best !

Thanks for the tip and code! I'll see if there's a reason for why I'm doing it the way I do. I probably did it that way when writing naalaa, for some dumb reason,  and then I just mimiced that for jail.
Reply
#26
Yo Marcus
in prolan u use for while loop this :

Code:
*
* Function: While
* ---------------
* while (<bool expr>) {[statements]}
*/
int While() {
   Token *loop = sToken;
   sLoopScope++;
   do {
       int res;
       GetNext(0);
       Expect('(');
       BoolExpression();
       Expect(')');
       if (sRegister[0].value.i == 0) break;
       Expect('{');
       res = ExecuteBlock();
       if (res == 1) {
           SkipBlock();
           sLoopScope--;
           return 0;
       }
       else if (res == 2) {
           sLoopScope--;
           return 2;
       }
       Expect('}');
       sToken = loop;
   } while (1);
   Expect('{');
   SkipBlock();
   sLoopScope--;
   return 0;
}

Marcus i don't see in your code any stack operation ,only
sLoopScope-- , IS that mean that is not possible  to have one while loop inside another?
Reply
#27
(07-05-2020, 07:49 AM)Aurel Wrote: Yo Marcus
in prolan u use for while loop this :

Code:
*
* Function: While
* ---------------
* while (<bool expr>) {[statements]}
*/
int While() {
   Token *loop = sToken;
   sLoopScope++;
   do {
       int res;
       GetNext(0);
       Expect('(');
       BoolExpression();
       Expect(')');
       if (sRegister[0].value.i == 0) break;
       Expect('{');
       res = ExecuteBlock();
       if (res == 1) {
           SkipBlock();
           sLoopScope--;
           return 0;
       }
       else if (res == 2) {
           sLoopScope--;
           return 2;
       }
       Expect('}');
       sToken = loop;
   } while (1);
   Expect('{');
   SkipBlock();
   sLoopScope--;
   return 0;
}

Marcus i don't see in your code any stack operation ,only
sLoopScope-- , IS that mean that is not possible  to have one while loop inside another?

Long time since I wrote that code. But I'm pretty sure you can have loops within loops without any problem. The second loop executes recursively (in C) through ExecuteBlock. The internal "scopes" are used for creating keys that the memory manager uses for searching through recursive hash tables. For exampel, if you call a function from the main program:

Code:
myFunc = function(paramOne, paramTwo) {
   localVarOne = 1;
   localVarTwo = 2;
};
myFunc(100, 200);

the scope will increase by one when the function call begins. So the keys for the parameters and local variabels are 1.paramOne, 1.param2, 1.localVarOne and 1.localVarTwo. If you made a recursive call inside myFunc:

Code:
myFunc = function(paramOne, paramTwo) {
   localVarOne = 1;
   localVarTwo = 2;
   this(300, 200); // infinite recursion.
};

the second call would use the keys 2.paramOne, 2.paramTwo and so on, to differentiate them from the surrounding call. 

Note that for example 2.paramOne is not a single hash key. 2 is a hash key in the main memory that leads to another hash table, in which paramOne is a key. The memory manager breaks down the keys while searching the tables.

I know, it's really stupid, but that's how it works Smile

You can download a fresh version of jail from here: https://naalaa.com/jail/jail.zip  It's just a backup of my working folder, so it's probably filled with crap.

Edit: And regarding scopes, only functions have their own scopes, loops do not. If you create a variable inside a loop, it will either belong to the main program or be local if you're inside a function. So, hm, its possible that sLoopScope is just used for error detection (functions use other scope variables) or it might be a left over from some experiment.
Reply
#28
Hi Marcus ..first thanks for reply and explanation
yeah ...i figured it when i looking into one Basic interpreter code on github.
And no ,your is not crap at all, i investigate many sources on github and there you can find a lot of craps
..really beleive it or not ..of course there are also a really great open source interpreters published ,some of them
are so damn complex that someone who looking first time in it must be totally confused.
see yaa.. Wink
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)