2012-04-25 12 views
0

私はコンパイラのために書いたこのJavaインタープリタをSmalltalkインタプリタに変換しようとしています。出来ますか?もしそうなら、見ていくには何がいいのでしょうか?私はSmalltalkに全く新しいです、今私にとっては奇妙に見えます。助けていただければ幸いです。プログラムに関するいくつかの情報:入力は以下のようなサンプルである中間コードファイルです。Smalltalk - SmalltalkでJavaプログラムを記述できますか?

数の階乗を計算する中間コードファイル、:

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プログラム:プログラミング言語間

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(); 


} 

}

+1

は、あなたの質問はすでにあなたがよりシンプルなもので開始することを示している...とのSmalltalkはオブジェクト指向言語です。 – home

+0

ああ私は私の知識が不足していることをお詫びします私は機能を持つ動的と混乱した訂正をしました – Yaba

+0

@ヤバ、デビッド(Simberon)はコードを手渡しました。その答えを受け入れるか、追加情報を求めてください。 –

答えて

4

ここでインタプリタのVisualWorksのSmalltalkのバージョンです:

'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]! ! 
+0

あなたはいつものようにデイブ。 :) –

+0

デイブ、なぜ "isVariableName:aString(aString isKindOf:String)と:[aString first isAlphabetic]"? –

+0

それとのより良い読むと思われる:。良い提案。 –

1

自動翻訳は、理論的には可能です少数の状況においてのみ実現可能であり、効率的ではない。仮想マシンのバイトコードの自動翻訳さえも効率的ではありません(そして、JVMはJava固有のもので、スモールトークバイトコードの変換はうまくいかないかもしれません)。

+0

ハッシュマップ、ファイルリーダー、ライターのようなもののためのsmalltalkの代替手段があるでしょうか? – Yaba

+0

本当にあります。対応するスモールトークとJavaライブラリが常に互換性のあるインタフェースを提供するとは限らないため、ライブラリにはさらに問題があります。 – geekosaur

+0

私は申し訳ありませんが、私はちょうど始めて、smalltalkの構文に従うのに苦労しています – Yaba

3

Smalltalkで中間コードのインタプリタを実装するのは難しいことではありませんが、少なくともSmalltalk:Collectionクラス、Streamクラスの基礎を理解し、IDEで快適にする必要があります。

Stephane Ducasse has great collection of free Smalltalk books

関連する問題