phubuh
11-04-2002, 11:27 AM
About two weeks ago, I was bored, and decided to write an interpreter. I had never done that before, so my code got quite ugly, but after a few rewrites it looks pretty good. Now, I'm sharing with you what I hacked out that night.
Welcome to the interactive Drims environment!
>> "Hello!".
String("Hello!")
>> 5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.
Integer(5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
>> [5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 squared].
Integer(25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
>> [squared 500].
Integer(250000)
>> [56 plus 40].
Integer(96)
>> [[10 plus 2] isGreaterThan [9 plus 3]].
Boolean(No)
>> $bool = [[10 plus 2] equals [9 plus 3]].
Boolean(Yes)
>> $bool.
Boolean(Yes)
>> [$bool negated].
Boolean(No)
>> [$system print "hello!"].
"hello!"
String("hello!")
>> $aCodeBlock = {[$system print "hello!"].}.
org.phubuh.drims2.parser.Codeblock@5483cd
>> [$bool test: ifTrue: $aCodeBlock ifFalse: {[$system print ":-("].}].
"hello!"
String("hello!")
>> $bool = [$bool negated].
Boolean(No)
>> [$bool test: ifTrue: $aCodeBlock ifFalse: {[$system print ":-("].}].
":-("
String(":-(")
>> [plus 10 59].
Integer(69)
>> [[$system readLine] toUpperCase].
hello! lol! lol! lol!
String("HELLO! LOL! LOL! LOL!")
>> [lengthOf "hello"].
Integer(5)
>> [9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 squared].
Integer(99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001)
>>
First of all: Everything is an object. A variable is an object, a codeblock is an object, a string is an object, an integer is an object, etc.
Second of all: Anything that does anything at all is a method. There are no special magic keywords. For example, the 'if' keyword that exists in basically all modern languages is implemented in Drims as a keyword message (I'll get to those later) on the Boolean object. So is 'while'.
In the last paragraph, I said 'methods' so you'd understand what I talked about -- but in Drims, methods are called messages. There are three types of messages:
Unary messages. These include Integer's 'squared' and String's 'toUpperCase'. They are called unary, because they know only one thing: which object to send themselves to.
Binary messages. Integer's 'plus', String's 'concatenatedWith', etc. These know which object to send themselves to, and they also have an object to give the receiver. (argument)
Keyword messages. So far, only Boolean's 'test'. These are the only messages that can give multiple arguments. What separates these from the run-of-the-mill f(x, y, z) is that all arguments are required to have names; f(firstArgument: x secondArgument:y thirdArgument:z). The keywords can be arranged however you want. They don't even have an internal order.
{ ... } blocks are what I like to call lambda subroutines. For those not into functional programming (lambda functions are usually in those languages, but I've heard that Python has them too. Oh well.), lambda functions are anonymous functions that can be passed as arguments and assigned to variables, and basically anything you can do with regular values. My codeblocks are like those, only you can't pass arguments to them.
Codeblocks are useful for stuff like Boolean's test. test takes two keyword arguments: ifTrue and ifFalse. (Actually, you can just pass ifFalse or ifTrue, but that doesn't matter.) Those arguments are supposed to be codeblocks. When called upon, the test method checks its own value, and sends the respective argument the 'evaluate' message, which evaluates the codeblock.
I haven't implemented the syntax for creating your own classes or methods yet, but I'll do that whenever I have the time. Actually, I haven't figured out how stuff like inheritance and polymorphism will work yes, but I guess I'll do that too.
So, any comments are gladly accepted. Preferrably constructive criticism though. :)
Welcome to the interactive Drims environment!
>> "Hello!".
String("Hello!")
>> 5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.
Integer(5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
>> [5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 squared].
Integer(25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
>> [squared 500].
Integer(250000)
>> [56 plus 40].
Integer(96)
>> [[10 plus 2] isGreaterThan [9 plus 3]].
Boolean(No)
>> $bool = [[10 plus 2] equals [9 plus 3]].
Boolean(Yes)
>> $bool.
Boolean(Yes)
>> [$bool negated].
Boolean(No)
>> [$system print "hello!"].
"hello!"
String("hello!")
>> $aCodeBlock = {[$system print "hello!"].}.
org.phubuh.drims2.parser.Codeblock@5483cd
>> [$bool test: ifTrue: $aCodeBlock ifFalse: {[$system print ":-("].}].
"hello!"
String("hello!")
>> $bool = [$bool negated].
Boolean(No)
>> [$bool test: ifTrue: $aCodeBlock ifFalse: {[$system print ":-("].}].
":-("
String(":-(")
>> [plus 10 59].
Integer(69)
>> [[$system readLine] toUpperCase].
hello! lol! lol! lol!
String("HELLO! LOL! LOL! LOL!")
>> [lengthOf "hello"].
Integer(5)
>> [9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 squared].
Integer(99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999 9980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001)
>>
First of all: Everything is an object. A variable is an object, a codeblock is an object, a string is an object, an integer is an object, etc.
Second of all: Anything that does anything at all is a method. There are no special magic keywords. For example, the 'if' keyword that exists in basically all modern languages is implemented in Drims as a keyword message (I'll get to those later) on the Boolean object. So is 'while'.
In the last paragraph, I said 'methods' so you'd understand what I talked about -- but in Drims, methods are called messages. There are three types of messages:
Unary messages. These include Integer's 'squared' and String's 'toUpperCase'. They are called unary, because they know only one thing: which object to send themselves to.
Binary messages. Integer's 'plus', String's 'concatenatedWith', etc. These know which object to send themselves to, and they also have an object to give the receiver. (argument)
Keyword messages. So far, only Boolean's 'test'. These are the only messages that can give multiple arguments. What separates these from the run-of-the-mill f(x, y, z) is that all arguments are required to have names; f(firstArgument: x secondArgument:y thirdArgument:z). The keywords can be arranged however you want. They don't even have an internal order.
{ ... } blocks are what I like to call lambda subroutines. For those not into functional programming (lambda functions are usually in those languages, but I've heard that Python has them too. Oh well.), lambda functions are anonymous functions that can be passed as arguments and assigned to variables, and basically anything you can do with regular values. My codeblocks are like those, only you can't pass arguments to them.
Codeblocks are useful for stuff like Boolean's test. test takes two keyword arguments: ifTrue and ifFalse. (Actually, you can just pass ifFalse or ifTrue, but that doesn't matter.) Those arguments are supposed to be codeblocks. When called upon, the test method checks its own value, and sends the respective argument the 'evaluate' message, which evaluates the codeblock.
I haven't implemented the syntax for creating your own classes or methods yet, but I'll do that whenever I have the time. Actually, I haven't figured out how stuff like inheritance and polymorphism will work yes, but I guess I'll do that too.
So, any comments are gladly accepted. Preferrably constructive criticism though. :)