Advertisement
objeckive

Untitled

Apr 23rd, 2021
2,259
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. use Collection.Generic;
  2.  
  3. class MiniLisp {
  4.     function : Main(args : String[]) ~ Nil {
  5.         if(args->Size() = 1) {
  6.             root := Parser->New(args[0])->Parse();
  7.             if(root <> Nil) {
  8.                 Evaluator->New(root)->Evaluate();
  9.             };
  10.         };
  11.     }
  12. }
  13.  
  14. #--- Evaluator ---
  15.  
  16. class Evaluator {
  17.     @root : Node;
  18.     @stack : Stack<Value>;
  19.     @symbol_tables : List<Hash<String, Value>>;
  20.     @is_debug : Bool;
  21.  
  22.     New(root : Node) {
  23.         @root := root;
  24.         @stack := Stack->New()<Value>;
  25.         @symbol_tables := List->New()<Hash<String, Value>>;
  26.         @is_debug := true;
  27.  
  28.         Value->Init();
  29.     }
  30.  
  31.     method : public : Evaluate() ~ Nil {
  32.         if(@is_debug) {
  33.             "\n--- Evaluate ---"->PrintLine();
  34.         };
  35.  
  36.         Evaluate(@root);
  37.     }
  38.  
  39.     method : Evaluate(node : Node) ~ Nil {
  40.         select(node->GetType()) {
  41.             label Node->Type->STR_LIT {
  42.                 found := false;
  43.                 name := node->GetStringValue();
  44.  
  45.                 @symbol_tables->Rewind();
  46.                 while(@symbol_tables->More() & <>found) {
  47.                     symbol_table := @symbol_tables->Get();
  48.                    
  49.                     value := symbol_table->Find(name);
  50.                     if(value <> Nil) {
  51.                         @stack->Push(value);
  52.                         found := true;
  53.                     };
  54.  
  55.                     @symbol_tables->Next();
  56.                 };
  57.  
  58.                 if(<>found) {
  59.                     "Unable to find variable '{$name}'"->ErrorLine();
  60.                     Runtime->Exit(1);
  61.                 };
  62.             }
  63.  
  64.             label Node->Type->LET {
  65.                 table := Hash->New()<String, Value>;
  66.                 @symbol_tables->AddFront(table);
  67.  
  68.                 children := node->GetChildren()<Node>;
  69.                 each(i : children) {
  70.                     child := children->Get(i);
  71.                     if(child->GetType() = Node->Type->LET_DEC) {
  72.                         name := child->GetStringValue();
  73.                         sub_child := child->GetChildren();
  74.                         Evaluate(sub_child->Get(0));
  75.                         table->Insert(name, @stack->Pop());
  76.                     }
  77.                     else {
  78.                         Evaluate(child);
  79.                     };
  80.                 };
  81.  
  82.                 @symbol_tables->RemoveFront();
  83.             }
  84.  
  85.             label Node->Type->LIST {
  86.                 children := node->GetChildren();
  87.                 each(i : children) {
  88.                     Evaluate(children->Get(i));
  89.                 };
  90.  
  91.                 list := Value->New(Value->Type->LIST);
  92.                 each(i : children) {
  93.                     child := @stack->Pop();
  94.                     if(child->GetType() = Value->Type->LIST) {
  95.                         list->AddList(child);
  96.                     }
  97.                     else {
  98.                         list->AddElement(child);
  99.                     };
  100.                 };
  101.                 @stack->Push(list);
  102.             }
  103.  
  104.             label Node->Type->CONS {
  105.                 children := node->GetChildren();
  106.                 each(i : children) {
  107.                     Evaluate(children->Get(i));
  108.                 };
  109.  
  110.                 list := Value->New(Value->Type->LIST);
  111.                 each(i : children) {
  112.                     list->AddElement(@stack->Pop());
  113.                 };
  114.                 @stack->Push(list);
  115.             }
  116.  
  117.             label Node->Type->WRITE {
  118.                 children := node->GetChildren();
  119.                 each(i : children) {
  120.                     Evaluate(children->Get(i));
  121.                 };
  122.  
  123.                 @stack->Pop()->ToString()->PrintLine();
  124.             }
  125.  
  126.             label Node->Type->LENGTH {
  127.                 children := node->GetChildren();
  128.                 each(i : children) {
  129.                     Evaluate(children->Get(i));
  130.                 };
  131.  
  132.                 list := @stack->Pop();
  133.                 @stack->Push(Value->New(list->GetListSize()));
  134.             }
  135.  
  136.             label Node->Type->EMPTY_LIST {
  137.                 @stack->Push(Value->EmptyList());
  138.             }
  139.  
  140.             label Node->Type->INT_LIT {
  141.                 @stack->Push(Value->New(node->GetIntValue()));
  142.             }
  143.  
  144.             label Node->Type->ADD {
  145.                 children := node->GetChildren();
  146.                 reverse(i : children) {
  147.                     Evaluate(children->Get(i));
  148.                 };
  149.  
  150.                 left := @stack->Pop();
  151.                 for(i := 1;  i < children->Size(); i += 1;) {
  152.                     right := @stack->Pop();
  153.                     left->SetIntValue(left->GetIntValue() + right->GetIntValue());
  154.                 };
  155.                 @stack->Push(left);
  156.             }
  157.  
  158.             label Node->Type->MUL {
  159.                 children := node->GetChildren();
  160.                 reverse(i : children) {
  161.                     Evaluate(children->Get(i));
  162.                 };
  163.  
  164.                 left := @stack->Pop();
  165.                 reverse(i : children) {
  166.                     right := @stack->Pop();
  167.                     left->SetIntValue(left->GetIntValue() * right->GetIntValue());
  168.                 };
  169.                 @stack->Push(left);
  170.             }
  171.  
  172.             label Node->Type->SUB {
  173.                 children := node->GetChildren();
  174.                 reverse(i : children) {
  175.                     Evaluate(children->Get(i));
  176.                 };
  177.  
  178.                 left := @stack->Pop();
  179.                 if(children->Size() = 1) {
  180.                     left->SetIntValue(left->GetIntValue() * -1);
  181.                 }
  182.                 else {
  183.                     for(i := 1;  i < children->Size(); i += 1;) {
  184.                         right := @stack->Pop();
  185.                         left->SetIntValue(left->GetIntValue() - right->GetIntValue());
  186.                     };
  187.                 };
  188.                 @stack->Push(left);
  189.             }
  190.  
  191.             label Node->Type->DIV {
  192.                 children := node->GetChildren();
  193.                 for(i := children->Size() - 1; i >= 0; i -= 1;) {
  194.                     Evaluate(children->Get(i));
  195.                 };
  196.  
  197.                 left := @stack->Pop();
  198.                 if(children->Size() = 1) {
  199.                     left->SetRealValue(1.0 / left->GetIntValue()->ToFloat());
  200.                 }
  201.                 else {
  202.                     for(i := 1;  i < children->Size(); i += 1;) {
  203.                         right := @stack->Pop();
  204.                         left->SetIntValue(left->GetIntValue() - right->GetIntValue());
  205.                     };
  206.                 };
  207.                 @stack->Push(left);
  208.             }
  209.         };
  210.     }
  211. }
  212.  
  213. class Value {
  214.     @type : Type;
  215.     @nil_value : static : Value;
  216.     @empty_list_value : static : Value;
  217.     @next_elem : Value;
  218.     @next_list : Value;
  219.     @int_value : Int;
  220.     @real_value : Float;
  221.     @str_value : String;
  222.  
  223.     enum Type := -300 {
  224.         LIST,
  225.         NIL_TYPE,
  226.         INT_TYPE,
  227.         REAL_TYPE,
  228.         STRING_TYPE
  229.     }
  230.  
  231.     function : Init() ~ Nil {
  232.         @nil_value := Value->New(Value->Type->NIL_TYPE);
  233.         @empty_list_value := Value->New(Value->Type->LIST);
  234.     }
  235.  
  236.     New(int_value : Int) {
  237.         @type := Value->Type->INT_TYPE;
  238.         @int_value := int_value;
  239.     }
  240.  
  241.     New(real_value : Float) {
  242.         @type := Value->Type->REAL_TYPE;
  243.         @real_value := real_value;
  244.     }
  245.  
  246.     New(type : Value->Type) {
  247.         @type := type;
  248.     }
  249.  
  250.     function : EmptyList() ~ Value {
  251.         return @empty_list_value;
  252.     }
  253.  
  254.     method : public : GetType() ~ Value->Type {
  255.         return @type;
  256.     }
  257.  
  258.     # list operations
  259.     method : public : GetNextElement() ~ Value {
  260.         return @next_elem;
  261.     }
  262.  
  263.     method : SetNextElement(next_elem : Value) ~ Nil {
  264.         @next_elem := next_elem;
  265.     }
  266.  
  267.     method : public : GetNextList() ~ Value {
  268.         return @next_list;
  269.     }
  270.    
  271.     method : SetNextList(next_list : Value) ~ Nil {
  272.         @next_list := next_list;
  273.     }
  274.  
  275.     method : public : AddElement(elem : Value) ~ Nil {
  276.         temp := @next_elem;
  277.  
  278.         if(elem->GetType() = Value->Type->LIST) {
  279.             @next_elem := elem->GetNextElement();
  280.         }
  281.         else {
  282.             @next_elem := elem;
  283.         };
  284.  
  285.         elem->SetNextElement(temp);
  286.     }  
  287.  
  288.     method : public : AddList(list : Value) ~ Nil {
  289.         if(list->GetType() = Value->Type->LIST) {
  290.             if(@next_list = Nil) {
  291.                 @next_list := list;
  292.             }
  293.             else {
  294.                 temp := @next_list;
  295.                 while(temp->GetNextList() <> Nil) {
  296.                     temp := temp->GetNextList();
  297.                 };
  298.                 temp->SetNextList(list);
  299.             };
  300.         };
  301.     }
  302.  
  303.     method : public : GetListSize() ~ Int {
  304.         if(@type = Value->Type->LIST) {
  305.             if(@next_elem = Nil & @next_list = Nil) {
  306.                 return 0;
  307.             }
  308.             else {
  309.                 count := 0;
  310.  
  311.                 elem := @next_elem;
  312.                 list := @next_list;
  313.                 if(elem <> Nil) {
  314.                     while(elem <> Nil) {
  315.                         count += 1;
  316.                         elem := elem->GetNextElement();
  317.                     };
  318.                 };
  319.                
  320.                 if(list <> Nil) {
  321.                     while(list <> Nil) {
  322.                         count += 1;
  323.                         list := list->GetNextList();
  324.                     };
  325.                 };
  326.  
  327.                 return count;
  328.             };
  329.         };
  330.  
  331.         return -1;
  332.     }
  333.  
  334.     # atom operations
  335.     method : public : GetIntValue() ~ Int {
  336.         return @int_value;
  337.     }
  338.  
  339.     method : public : SetIntValue(int_value : Int) ~ Nil {
  340.         @type := Value->Type->INT_TYPE;
  341.         @int_value := int_value;
  342.     }
  343.  
  344.     method : public : GetRealValue() ~ Float {
  345.         return @real_value;
  346.     }
  347.  
  348.     method : public : SetRealValue(real_value : Float) ~ Nil {
  349.         @type := Value->Type->REAL_TYPE;
  350.         @real_value := real_value;
  351.     }
  352.  
  353.     # other
  354.     method : public : ToString() ~ String {
  355.         buffer := "";
  356.  
  357.         select(@type) {
  358.             label Value->Type->INT_TYPE {
  359.                 buffer += @int_value->ToString();
  360.             }
  361.  
  362.             label Value->Type->REAL_TYPE {
  363.                 buffer += @real_value->ToString();
  364.             }
  365.  
  366.             label Value->Type->STRING_TYPE {
  367.                 buffer += @str_value;
  368.             }
  369.  
  370.             label Value->Type->LIST {
  371.                 if(@next_elem = Nil & @next_list = Nil) {
  372.                     buffer += "NIL";
  373.                 }
  374.                 else {
  375.                     buffer += "(";
  376.                    
  377.                     elem := @next_elem;
  378.                     list := @next_list;
  379.                     if(elem <> Nil) {
  380.                         while(elem <> Nil) {
  381.                             buffer += elem->ToString();
  382.                             elem := elem->GetNextElement();
  383.                             if(elem <> Nil | list <> Nil) {
  384.                                 buffer += ", ";
  385.                             };
  386.                         };
  387.                     };
  388.                    
  389.                     if(list <> Nil) {
  390.                         while(list <> Nil) {
  391.                             buffer += list->ToString();
  392.                             list := list->GetNextList();
  393.                             if(list <> Nil) {
  394.                                 buffer += ", ";
  395.                             };
  396.                         };
  397.                     };
  398.  
  399.                     buffer += ")";
  400.                 };
  401.             }
  402.  
  403.             label Value->Type->NIL_TYPE {
  404.                 buffer += "NIL";
  405.             }
  406.         };
  407.  
  408.         return buffer;
  409.     }
  410. }
  411.  
  412. #--- Parser ---
  413.  
  414. class Parser {
  415.     @input : String;
  416.     @tokens : Vector<Token>;
  417.     @token_pos : Int;
  418.     @level : Int;
  419.     @error : Bool;
  420.     @is_debug : Bool;
  421.    
  422.     New(input : String) {
  423.         @input := input;
  424.         @is_debug := true;
  425.     }
  426.  
  427.     method : public : Parse() ~ Node {
  428.         @tokens := Scanner->New()->Scan(@input);
  429.  
  430.         if(@is_debug) {
  431.             "--- Input ---\n\"{$@input}\""->PrintLine();
  432.            
  433.             "\n--- Tokens ---"->PrintLine();
  434.             each(i : @tokens) {
  435.                 value := @tokens->Get(i);
  436.                 "{$i}: '{$value}'"->PrintLine();
  437.             };
  438.             "\n--- Expressions ---"->PrintLine();
  439.         };
  440.  
  441.         root := Expression(0);
  442.         if(@token_pos <> @tokens->Size()) {
  443.             @error := true;
  444.             "*** unexpected tokens ***"->ErrorLine();
  445.             return Nil;
  446.         };
  447.  
  448.         if(@is_debug) {
  449.             if(root <> Nil) {
  450.                 "\n--- Tree ---"->PrintLine();
  451.                 root->ToString()->PrintLine();
  452.             };
  453.         };
  454.  
  455.         return root;
  456.     }
  457.  
  458.     method : public : NextToken() ~ Nil {
  459.         @token_pos += 1;
  460.     }
  461.  
  462.     method : GetTokenType() ~ Token->Type {
  463.         if(@token_pos < @tokens->Size()) {
  464.             return @tokens->Get(@token_pos)->GetType();
  465.         };
  466.  
  467.         return Token->Type->OTHER;
  468.     }
  469.  
  470.     method : Match(type : Token->Type) ~ Bool {
  471.         return GetTokenType() = type;
  472.     }
  473.  
  474.     method : public : Expression(depth : Int) ~ Node {
  475.         node : Node;
  476.  
  477.         if(@is_debug) {
  478.             length := @tokens->Size();
  479.             "Expression: pos=({$@token_pos},{$length}); depth={$depth}"->PrintLine();
  480.         };
  481.  
  482.         is_eval := true;
  483.         if(Match(Token->Type->QUOTE)) {
  484.             is_eval := false;
  485.             NextToken();
  486.         };
  487.  
  488.         if(Match(Token->Type->OPRN)) {
  489.             NextToken();
  490.             @level += 1;
  491.            
  492.             if(@token_pos + 2 < @tokens->Size()) {
  493.                 select(@tokens->Get(@token_pos)->GetType()) {
  494.                     label Token->Type->ADD:
  495.                     label Token->Type->SUB:
  496.                     label Token->Type->MUL:
  497.                     label Token->Type->DIV: {
  498.                         if(@is_debug) {
  499.                             "\t[+,-,*,/]"->PrintLine();
  500.                         };
  501.  
  502.                         node := Node->New(GetTokenType());
  503.                         if(<>Operands(node, depth)) {
  504.                             return Nil;
  505.                         };
  506.                     }
  507.  
  508.                     label Token->Type->LIST_KEYWORD: {
  509.                         if(@is_debug) {
  510.                             "\tList"->PrintLine();
  511.                         };
  512.  
  513.                         node := Node->New(Node->Type->LIST);
  514.                         if(<>Operands(node, depth)) {
  515.                             return Nil;
  516.                         };
  517.                     }
  518.  
  519.                     label Token->Type->WRITE_KEYWORD: {
  520.                         if(@is_debug) {
  521.                             "\tWrite"->PrintLine();
  522.                         };
  523.  
  524.                         node := Node->New(Node->Type->WRITE);
  525.                         if(<>Operands(node, depth)) {
  526.                             return Nil;
  527.                         };
  528.  
  529.                         if(node->GetChildren()->Size() <> 1) {
  530.                             @error := true;
  531.                             "*** 'write' operation takes 1 operand ***"->ErrorLine();
  532.                             return Nil;
  533.                         };
  534.                     }
  535.  
  536.                     label Token->Type->CONS_KEYWORD: {
  537.                         if(@is_debug) {
  538.                             "\tCons"->PrintLine();
  539.                         };
  540.  
  541.                         node := Node->New(Node->Type->CONS);
  542.                         if(<>Operands(node, depth)) {
  543.                             return Nil;
  544.                         };
  545.  
  546.                         if(node->GetChildren()->Size() <> 2) {
  547.                             @error := true;
  548.                             "*** 'cons' operation takes 2 operands ***"->ErrorLine();
  549.                             return Nil;
  550.                         };
  551.                     }
  552.  
  553.                     label Token->Type->LET_KEYWORD: {
  554.                         if(@is_debug) {
  555.                             "\tLet"->PrintLine();
  556.                         };
  557.  
  558.                         NextToken();
  559.                         if(GetTokenType() <> Token->Type->OPRN) {
  560.                             @error := true;
  561.                             "*** expected '(' ***"->ErrorLine();
  562.                             return Nil;
  563.                         };
  564.  
  565.                         node := Node->New(Node->Type->LET);
  566.                         if(<>Operands(node, depth)) {
  567.                             return Nil;
  568.                         };
  569.  
  570.                         if(GetTokenType() <> Token->Type->CPRN) {
  571.                             expr := Expression(depth);
  572.                             if(expr <> Nil) {
  573.                                 node->AddChild(expr);
  574.                             };
  575.  
  576.                             if(GetTokenType() <> Token->Type->CPRN) {
  577.                                 @error := true;
  578.                                 "*** expected ')' ***"->ErrorLine();
  579.                                 return Nil;
  580.                             };
  581.                         };
  582.  
  583.                         NextToken();
  584.                     }
  585.  
  586.                     label Token->Type->STR_LIT: {
  587.                         value := @tokens->Get(@token_pos)->GetStringValue();
  588.                         if(@is_debug) {
  589.                             "\tStr_Lit; value={$value}"->PrintLine();
  590.                         };
  591.  
  592.                         node := Node->New(Node->Type->LET_DEC, value);
  593.                         if(<>Operands(node, depth)) {
  594.                             return Nil;
  595.                         };
  596.                     }
  597.  
  598.                     label Token->Type->LENGTH_KEYWORD: {
  599.                         if(@is_debug) {
  600.                             "\tLength"->PrintLine();
  601.                         };
  602.  
  603.                         node := Node->New(Node->Type->LENGTH);
  604.                         if(<>Operands(node, depth)) {
  605.                             return Nil;
  606.                         };
  607.  
  608.                         if(node->GetChildren()->Size() <> 1) {
  609.                             @error := true;
  610.                             "*** 'length' operation takes 1 operand ***"->ErrorLine();
  611.                             return Nil;
  612.                         };
  613.                     }
  614.  
  615.                     label Token->Type->CPRN: {
  616.                         if(@is_debug) {
  617.                             "\tEmpty_List"->PrintLine();
  618.                         };
  619.  
  620.                         node := Node->New(Node->Type->EMPTY_LIST);
  621.                     }
  622.  
  623.                     other: {
  624.                         token_id := GetTokenType()->As(Int);
  625.                         @error := true;
  626.                         "*** Error: unknown operation: id={$token_id} ***"->ErrorLine();
  627.                         return Nil;
  628.                     }
  629.                 };
  630.             }
  631.             else if(Match(Token->Type->CPRN)) {
  632.                 if(@is_debug) {
  633.                     "\tEmpty_List"->PrintLine();
  634.                 };
  635.  
  636.                 node := Node->New(Node->Type->EMPTY_LIST);
  637.             }
  638.             else {
  639.                 @error := true;
  640.                 "*** Error: operation requires at least 1 operand ***"->ErrorLine();
  641.                 return Nil;
  642.             };
  643.         }
  644.         else if(Match(Token->Type->CPRN)) {
  645.             NextToken();
  646.             @level -= 1;
  647.         }
  648.         else if(Match(Token->Type->INT_LIT)) {
  649.             value := @tokens->Get(@token_pos)->GetIntValue();
  650.             if(@is_debug) {
  651.                 "\tInt_Lit; value={$value}"->PrintLine();
  652.             };
  653.             node := Node->New(value);
  654.             NextToken();
  655.         }
  656.         else if(Match(Token->Type->STR_LIT)) {
  657.             value := @tokens->Get(@token_pos)->GetStringValue();
  658.             if(@is_debug) {
  659.                 "\tStr_Lit; value={$value}"->PrintLine();
  660.             };
  661.             node := Node->New(Node->Type->STR_LIT, value);
  662.             NextToken();
  663.         }
  664.         else {
  665.             token_id := GetTokenType()->As(Int);
  666.             @error := true;
  667.             "*** Error: unknown token: id={$token_id} ***"->ErrorLine();
  668.             NextToken();
  669.             return Nil;
  670.         };
  671.  
  672.         if(node <> Nil) {
  673.             node->SetEval(is_eval);
  674.         };
  675.  
  676.         return node;
  677.     }
  678.  
  679.     method : Operands(node : Node, depth : Int) ~ Bool {
  680.         NextToken();
  681.  
  682.         cur_level := @level;
  683.         do {
  684.             child := Expression(depth + 1);
  685.             if(@error) {
  686.                 return false;
  687.             };
  688.  
  689.             if(child <> Nil) {
  690.                 node->AddChild(child);
  691.             };
  692.         }
  693.         while(cur_level <= @level);
  694.  
  695.         return true;
  696.     }
  697. }
  698.  
  699. class Node {
  700.     @type : Node->Type;
  701.     @is_eval : Bool;
  702.     @int_value : Int;
  703.     @real_value : Float;
  704.     @str_value : String;
  705.     @children : Vector<Node>;
  706.  
  707.     enum Type := -200 {
  708.         ADD,
  709.         SUB,
  710.         MUL,
  711.         DIV,
  712.         LIST,
  713.         LET,
  714.         LET_DEC,
  715.         CONS,
  716.         WRITE,
  717.         LENGTH,
  718.         EMPTY_LIST,
  719.         INT_LIT,
  720.         REAL_LIT,
  721.         STR_LIT
  722.     }
  723.  
  724.     New(int_value : Int) {
  725.         @type := Node->Type->INT_LIT;
  726.         @int_value := int_value;
  727.     }
  728.  
  729.     New(real_value : Float) {
  730.         @type := Node->Type->REAL_LIT;
  731.         @real_value := real_value;
  732.     }
  733.  
  734.     New(type : Node->Type, str_value : String) {
  735.         @type := type;
  736.         @str_value := str_value;
  737.     }
  738.  
  739.     New(type : Node->Type) {
  740.         @type := type;
  741.     }
  742.  
  743.     New(type : Token->Type) {
  744.         select(type) {
  745.             label Token->Type->ADD {
  746.                 @type := Node->Type->ADD;
  747.             }
  748.  
  749.             label Token->Type->SUB {
  750.                 @type := Node->Type->SUB;
  751.             }
  752.            
  753.             label Token->Type->MUL {
  754.                 @type := Node->Type->MUL;
  755.             }
  756.            
  757.             label Token->Type->DIV {
  758.                 @type := Node->Type->DIV;
  759.             }
  760.         };
  761.     }
  762.  
  763.     method : public : SetEval(is_eval : Bool) ~ Nil {
  764.         @is_eval := is_eval;
  765.     }
  766.  
  767.     method : public : GetEval() ~ Bool {
  768.         return @is_eval;
  769.     }
  770.  
  771.     method : public : GetType() ~ Node->Type {
  772.         return @type;
  773.     }
  774.  
  775.     method : public : GetIntValue() ~ Int {
  776.         return @int_value;
  777.     }
  778.  
  779.     method : public : GetRealValue() ~ Float {
  780.         return @real_value;
  781.     }
  782.  
  783.     method : public : GetStringValue() ~ String {
  784.         return @str_value;
  785.     }
  786.  
  787.     method : public : AddChild(node : Node) ~ Nil {
  788.         if(@children = Nil) {
  789.             @children := Vector->New()<Node>;
  790.         };
  791.  
  792.         @children->AddBack(node);
  793.     }
  794.  
  795.     method : public : GetChildren() ~ Vector<Node> {
  796.         return @children;
  797.     }
  798.  
  799.     method : public : ToString() ~ String {
  800.         return ToString(0);
  801.     }
  802.  
  803.     method : public : ToString(level : Int) ~ String {
  804.         buffer := "";
  805.  
  806.         each(l : level) {
  807.             buffer += "  ";
  808.         };
  809.         buffer += "[";
  810.  
  811.         select(@type) {
  812.             label Node->Type->ADD {
  813.                 buffer += "+";
  814.             }
  815.  
  816.             label Node->Type->LIST {
  817.                 buffer += "list";
  818.             }
  819.  
  820.             label Node->Type->WRITE {
  821.                 buffer += "write";
  822.             }
  823.  
  824.             label Node->Type->LENGTH {
  825.                 buffer += "length";
  826.             }
  827.  
  828.             label Node->Type->LET {
  829.                 buffer += "let";
  830.             }
  831.  
  832.             label Node->Type->LET_DEC {
  833.                 buffer += "let_dec '{$@str_value}'";
  834.             }
  835.  
  836.             label Node->Type->EMPTY_LIST {
  837.                 buffer += "empty_list";
  838.             }
  839.  
  840.             label Node->Type->SUB {
  841.                 buffer += "-";
  842.             }
  843.  
  844.             label Node->Type->MUL {
  845.                 buffer += "*";
  846.             }
  847.  
  848.             label Node->Type->DIV {
  849.                 buffer += "/";
  850.             }
  851.  
  852.             label Node->Type->INT_LIT {
  853.                 buffer += @int_value->ToString();
  854.             }
  855.  
  856.             label Node->Type->REAL_LIT {
  857.                 buffer += @real_value->ToString();
  858.             }
  859.  
  860.             label Node->Type->STR_LIT {
  861.                 buffer += @str_value;
  862.             }
  863.         };
  864.  
  865.         if(@children <> Nil) {
  866.             each(i : @children) {
  867.                 buffer += '\n';
  868.                 buffer += @children->Get(i)->ToString(level + 1);
  869.             };
  870.            
  871.         };
  872.         buffer += "]";
  873.  
  874.         return buffer;
  875.     }
  876. }
  877.  
  878. #--- Scanner ---
  879.  
  880. class Scanner {
  881.     @keywords : Hash<String, Token->Type>;
  882.  
  883.     New() {
  884.         @keywords := Hash->New()<String, Token->Type>;
  885.         @keywords->Insert("let", Token->Type->LET_KEYWORD);
  886.         @keywords->Insert("write", Token->Type->WRITE_KEYWORD);
  887.         @keywords->Insert("list", Token->Type->LIST_KEYWORD);
  888.         @keywords->Insert("cons", Token->Type->CONS_KEYWORD);
  889.         @keywords->Insert("length", Token->Type->LENGTH_KEYWORD);
  890.     }
  891.  
  892.     method : public : Scan(input : String) ~ Vector<Token> {
  893.         tokens := Vector->New()<Token>;
  894.  
  895.         each(i : input) {
  896.             while(input->Get(i) = ' ' | input->Get(i) = '\r' | input->Get(i) = '\n' | input->Get(i) = '\t') {
  897.                 i += 1;
  898.             };
  899.  
  900.             if(input->Get(i)->IsChar()) {
  901.                 start := i;
  902.                 while(input->Get(i)->IsChar() | input->Get(i) = '_') {
  903.                     i += 1;
  904.                 };
  905.                 ident := input->SubString(start, i - start);
  906.  
  907.                 found := @keywords->Find(ident);
  908.                 if(found <> 0) {
  909.                     tokens->AddBack(Token->New(found));                
  910.                 }
  911.                 else {
  912.                     tokens->AddBack(Token->New(Token->Type->STR_LIT, ident));
  913.                 };
  914.  
  915.                 i -= 1;
  916.             }
  917.             else if(input->Get(i)->IsDigit()) {
  918.                 is_real := false;
  919.  
  920.                 start := i;
  921.                 while(input->Get(i)->IsDigit() | input->Get(i) = '.') {
  922.                     if(input->Get(i) = '.') {
  923.                         is_real := true;
  924.                     };
  925.                     i += 1;
  926.                 };
  927.  
  928.                 value := input->SubString(start, i - start);
  929.                 if(is_real) {
  930.                     tokens->AddBack(Token->New(value->ToFloat()));
  931.                 }
  932.                 else {
  933.                     tokens->AddBack(Token->New(value->ToInt()));
  934.                 };
  935.                 i -= 1;
  936.             }
  937.             else {
  938.                 select(input->Get(i)) {
  939.                     label '(' {
  940.                         tokens->AddBack(Token->New(Token->Type->OPRN));
  941.                     }
  942.  
  943.                     label ')' {
  944.                         tokens->AddBack(Token->New(Token->Type->CPRN));
  945.                     }
  946.  
  947.                     label '+' {
  948.                         tokens->AddBack(Token->New(Token->Type->ADD));
  949.                     }
  950.  
  951.                     label '-' {
  952.                         tokens->AddBack(Token->New(Token->Type->SUB));
  953.                     }
  954.  
  955.                     label '*' {
  956.                         tokens->AddBack(Token->New(Token->Type->MUL));
  957.                     }
  958.  
  959.                     label '/' {
  960.                         tokens->AddBack(Token->New(Token->Type->DIV));
  961.                     }
  962.  
  963.                     label '\'' {
  964.                         tokens->AddBack(Token->New(Token->Type->QUOTE));
  965.                     }
  966.  
  967.                     other {
  968.                         tokens->AddBack(Token->New(Token->Type->OTHER));
  969.                     }
  970.                 };
  971.             };
  972.         };
  973.  
  974.         return tokens;
  975.     }
  976. }
  977.  
  978. class Token {
  979.     @type : Token->Type;
  980.     @str_value : String;
  981.     @int_value : Int;
  982.     @real_value : Float;
  983.  
  984.     enum Type := -100 {
  985.         WRITE_KEYWORD,
  986.         LET_KEYWORD,   
  987.         LIST_KEYWORD,
  988.         CONS_KEYWORD,
  989.         LENGTH_KEYWORD,
  990.         INT_LIT, # -95
  991.         REAL_LIT,
  992.         STR_LIT,
  993.         OPRN,
  994.         CPRN,
  995.         ADD, # -90
  996.         SUB,
  997.         MUL,
  998.         DIV,
  999.         QUOTE,
  1000.         OTHER # -85
  1001.     }
  1002.  
  1003.     New(type : Token->Type) {
  1004.         @type := type;
  1005.     }
  1006.  
  1007.     New(type : Token->Type, str_value : String) {
  1008.         @type := type;
  1009.         @str_value := str_value;
  1010.     }
  1011.  
  1012.     New(int_value : Int) {
  1013.         @type := Type->INT_LIT;
  1014.         @int_value := int_value;
  1015.     }
  1016.  
  1017.     New(real_value : Float) {
  1018.         @type := Type->REAL_LIT;
  1019.         @real_value := real_value;
  1020.     }
  1021.  
  1022.     method : public : GetType() ~ Token->Type {
  1023.         return @type;
  1024.     }
  1025.  
  1026.     method : public : GetStringValue() ~ String {
  1027.         return @str_value;
  1028.     }
  1029.  
  1030.     method : public : GetIntValue() ~ Int {
  1031.         return @int_value;
  1032.     }
  1033.  
  1034.     method : public : GetRealValue() ~ Float {
  1035.         return @real_value;
  1036.     }
  1037.  
  1038.     method : public : ToString() ~ String {
  1039.         select(@type) {
  1040.             label Type->OPRN {
  1041.                 return "(";
  1042.             }
  1043.  
  1044.             label Type->CPRN {
  1045.                 return ")";
  1046.             }
  1047.            
  1048.             label Type->ADD {
  1049.                 return "+";
  1050.             }
  1051.            
  1052.             label Type->SUB {
  1053.                 return "-";
  1054.             }
  1055.  
  1056.             label Type->MUL {
  1057.                 return "*";
  1058.             }
  1059.            
  1060.             label Type->DIV {
  1061.                 return "/";
  1062.             }
  1063.  
  1064.             label Type->WRITE_KEYWORD {
  1065.                 return "write";
  1066.             }
  1067.  
  1068.             label Type->LENGTH_KEYWORD {
  1069.                 return "length";
  1070.             }
  1071.  
  1072.             label Type->LIST_KEYWORD {
  1073.                 return "list";
  1074.             }
  1075.  
  1076.             label Type->CONS_KEYWORD {
  1077.                 return "cons";
  1078.             }
  1079.  
  1080.             label Type->LET_KEYWORD {
  1081.                 return "let";
  1082.             }
  1083.  
  1084.             label Type->STR_LIT {
  1085.                 return @str_value;
  1086.             }
  1087.            
  1088.             label Type->INT_LIT {
  1089.                 return @int_value->ToString();
  1090.             }
  1091.            
  1092.             label Type->REAL_LIT {
  1093.                 return @real_value->ToString();
  1094.             }
  1095.  
  1096.             other {
  1097.                 return "?";
  1098.             }
  1099.         };
  1100.     }
  1101. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement