Reputation: 304
I am trying to convert this Java interpreter I wrote for my compiler to a Smalltalk interpreter. Is it possible? If so, what would be a good resources to look at? I am completely new to Smalltalk, looks weird to me for now. I would appreciate any help, thanks. Some more info on the program: The input would be an intermediate code file a sample of which is as below.
Intermediate code file, which computes the factorial of a number:
read
store x
push x
store i
push 1.0
store fact
push i
push 1.0
greater
testfgoto 21
push fact
push i
multiply
store fact
push i
push 1.0
minus
store i
push 1.0
testtgoto 7
push fact
print
end
JavaExecutor.java Program :
public void executor(){
String operation = null;
StringTokenizer tokens = null;
String key,value = null;
Double tempVar = null;
// Traverse the Arraylist to get the operations
for(int i=0; i < operations.size(); i++){
operation = (String)operations.get(i);
System.out.println("Operation -------"+ operation);
tokens = new StringTokenizer(operation);
while(tokens.hasMoreTokens()){
key = tokens.nextToken();
//System.out.println("KEY "+ key);
if(key.toUpperCase().equals("PUSH")){
//System.out.println("Push Operation");
value = (String)tokens.nextToken();
//System.out.println("value "+ value);
if(checkforVaribaleName(value)){
stack.push((Double)assignments.get(value));
System.out.println("PUSH"+ (Double)assignments.get(value));
}
else if(value != null){
stack.push(Double.parseDouble(value));
System.out.println("PUSH" + value);
} else{
stack.push(0.0);
System.out.println("PUSH" + 0.0);
}
break;
}else if(key.toUpperCase().equals("POP")){
//NO LOGIC
break;
}else if(key.toUpperCase().equals("READ")){
//System.out.println("Read Operation");
tempVar = readDoubleFromConsole();
stack.push(tempVar);
System.out.println("PUSHP :"+tempVar);
break;
}else if(key.toUpperCase().equals("WRITE")){
break;
}else if(key.toUpperCase().equals("MULTIPLY")){
//System.out.println("MULTIPLY operation");
Double first = (Double)stack.pop();
Double second = (Double)stack.pop();
stack.push(first*second);
System.out.println("PUSH "+ first*second);
break;
}else if(key.toUpperCase().equals("DIVIDE")){
Double first = (Double)stack.pop();
Double second = (Double)stack.pop();
stack.push(second/first);
break;
}else if(key.toUpperCase().equals("PLUS")){
Double first = (Double)stack.pop();
Double second = (Double)stack.pop();
stack.push(second+first);
break;
}else if(key.toUpperCase().equals("MINUS")){
Double first = (Double)stack.pop();
Double second = (Double)stack.pop();
stack.push(second-first);
System.out.println("PUSH "+ (second-first));
break;
}else if(key.toUpperCase().equals("GREATER")){
//System.out.println("GREATER operation");
Double first = (Double)stack.pop();
System.out.println("POP :"+first);
Double second = (Double)stack.pop();
System.out.println("POP "+ second);
if(second>first){
stack.push(1.0);
}
else{
stack.push(0.0);
}
break;
}else if(key.toUpperCase().equals("LESS")){
Double first = (Double)stack.pop();
Double second = (Double)stack.pop();
if(second<first){
stack.push(1.0);
}
else{
stack.push(0.0);
}
break;
}else if(key.toUpperCase().equals("EQUAL")){
Double first = (Double)stack.pop();
Double second = (Double)stack.pop();
if(second==first){
stack.push(1.0);
}
else{
stack.push(0.0);
}
break;
}else if(key.toUpperCase().equals("STORE")){
//System.out.println("Store operation");
value = (String)tokens.nextToken();
assignments.put(value, (Double)stack.pop());
System.out.println("POP :"+assignments.get(value));
break;
}else if(key.toUpperCase().equals("TESTFGOTO")){
value = (String)tokens.nextToken();
if((Double)stack.pop() == 0.0){
System.out.println("POP " +0.0);
i = Integer.parseInt(value)-2;
}
break;
}else if(key.toUpperCase().equals("TESTTGOTO")){
value = (String)tokens.nextToken();
if((Double)stack.pop() == 1.0){
System.out.println("POP " +1.0);
i = (Integer.parseInt(value)-2);
System.out.println(i);
}
break;
}else if(key.toUpperCase().equals("PRINT")){
//System.out.println("PRINT operation");
System.out.println("Result "+stack.pop());
break;
}else if(key.toUpperCase().equals("END")){
System.out.println("Execution Completed");
System.exit(0);
}
}
}
}
public static void main(String args[])
{
String fileName = null;
if(args.length > 0)
{
fileName = args[0];
}
else{
System.out.println("Usage : JavaExecutor fileName.inp");
System.exit(0);
}
JavaExecutor j = new JavaExecutor(fileName);
j.readFromFile();
j.executor();
}
}
Upvotes: 0
Views: 635
Reputation: 2847
Here's a VisualWorks Smalltalk version of the interpreter:
'From VisualWorks, 7.8 of March 30, 2011 on May 1, 2012 at 9:47:31 PM'!
CodeComponent create: #package named: 'IntermediateInterpreter'!"Package IntermediateInterpreter*"!
CodeComponent create: #package named: 'IntermediateInterpreter'!
Smalltalk defineClass: #IntermediateInterpreter
superclass: #{Core.Object}
indexedType: #none
private: false
instanceVariableNames: 'lines currentLineNumber variables stack commands '
classInstanceVariableNames: ''
imports: ''
category: ''!
!IntermediateInterpreter class methodsFor: 'instance creation'!
new
^super new initialize
! !
!IntermediateInterpreter methodsFor: 'initialize-release'!
initialize
stack := OrderedCollection new.
variables := Dictionary new.
lines := OrderedCollection new.
self initializeCommands
!
initializeCommands
commands := Dictionary new.
commands
at: 'READ' put: [:values | stack add: (self tokenize: (Dialog request: 'value?' initialAnswer: ''))];
at: 'STORE' put: [:values | variables at: values second put: stack removeLast];
at: 'PUSH' put: [:values | stack add: ((self isVariableName: values second) ifTrue: [variables at: values second] ifFalse: [values second])];
at: 'GREATER' put: [:values | | a b | b := stack removeLast. a := stack removeLast. stack add: (a > b ifTrue: [1.0] ifFalse: [0.0])];
at: 'MULTIPLY' put: [:values | | a b | b := stack removeLast. a := stack removeLast. stack add: a * b ];
at: 'MINUS' put: [:values | | a b | b := stack removeLast. a := stack removeLast. stack add: a - b ];
at: 'TESTFGOTO' put: [:values | (stack removeLast - 0.0) abs < 0.01 ifTrue: [currentLineNumber := values second]];
at: 'TESTTGOTO' put: [:values | (stack removeLast - 1.0) abs < 0.01 ifTrue: [currentLineNumber := values second]];
at: 'PRINT' put: [:values | Transcript show: stack removeLast printString; cr];
at: 'END' put: [:values | currentLineNumber := 0]! !
!IntermediateInterpreter methodsFor: 'testing'!
isVariableName: aString
(aString isKindOf: String) ifFalse: [^false].
^aString first isAlphabetic! !
!IntermediateInterpreter methodsFor: 'interpreting'!
interpret: aString
self createLinesFrom: aString.
currentLineNumber := 1.
self interpret!
interpret
| tokens |
[currentLineNumber = 0] whileFalse:
[tokens := lines at: currentLineNumber.
Transcript show: tokens printString; cr.
currentLineNumber := currentLineNumber + 1.
(commands at: tokens first asUppercase
ifAbsent: [self error: 'Unknown command']) value: tokens]!
tokenizeLine: aString
^(((aString tokensBasedOn: Character space)
reject: [:each | each isEmpty]) collect: [:each | self tokenize: each]) asArray!
tokenizeCurrentLine
^(((lines at: currentLineNumber) tokensBasedOn: Character space)
reject: [:each | each isEmpty]) collect: [:each | self tokenize: each]!
createLinesFrom: aString
| stream |
stream := aString readStream.
[stream atEnd] whileFalse: [lines add: (self tokenizeLine: (stream upTo: Character cr))]!
tokenize: each
^(self isVariableName: each)
ifTrue: [each]
ifFalse: [Number readFrom: each readStream]! !
Upvotes: 4
Reputation: 4392
It should not be to hard at all to implement interpreter for your intermediate code in Smalltalk, but you need to know at least basics of Smalltalk: Collection classes, Stream classes, and making yourself comfortable in IDE.
Stephane Ducasse has great collection of free Smalltalk books
Upvotes: 3
Reputation: 61457
Automated translation between programming languages is possible in theory, feasible only in a small number of circumstances, efficient in very few of those. Even automated translation of virtual machine bytecode is usually not efficient (and the JVM is rather Java-specific; translating to/from Smalltalk bytecode may not go well).
Upvotes: 1