sidef_interpreter.sf 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/ruby
  2. # A demo concept for a Sidef interpreter.
  3. #
  4. ## Boolean type
  5. #
  6. class SBool(Bool val) {
  7. }
  8. #
  9. ## String type + methods
  10. #
  11. class SString(String val) {
  12. method +(SString arg) {
  13. SString(val + arg.val);
  14. }
  15. method say() {
  16. self + SString("\n") -> print;
  17. }
  18. method print() {
  19. SBool(Sys.print(val));
  20. }
  21. }
  22. class Interpreter {
  23. #
  24. ## Expression executor
  25. #
  26. method execute_expr(statement) {
  27. statement.has_key(:self) || die "Invalid AST!";
  28. var self_obj = statement{:self};
  29. if (self_obj.is_a(Hash)) {
  30. self_obj = self.execute(self_obj);
  31. }
  32. if (statement.has_key(:call)) {
  33. statement{:call}.each { |call|
  34. var meth = call{:method};
  35. if (call.has_key(:arg)) {
  36. var args = call{:arg}.map {|arg|
  37. arg.is_a(Hash) ? self.execute_expr(arg) : arg
  38. };
  39. self_obj = self_obj.(meth)(args...);
  40. }
  41. else {
  42. self_obj = self_obj.(meth);
  43. }
  44. }
  45. };
  46. return self_obj;
  47. }
  48. #
  49. ## Parse-tree executor
  50. #
  51. method execute(structure) {
  52. var results = [];
  53. structure.has_key(:main) || die "Invalid AST!";
  54. structure{:main}.each { |statement|
  55. results.append(self.execute_expr(statement));
  56. };
  57. results[-1];
  58. }
  59. }
  60. #
  61. ## The AST
  62. #
  63. var ast = Hash.new(
  64. :main => [
  65. Hash.new(
  66. :call => [Hash.new(:method => "print")],
  67. :self => Hash.new(
  68. :main => [
  69. Hash.new(
  70. :call => [Hash.new(:method => "+", :arg => [Hash.new(:self => SString("llo"))])],
  71. :self => SString("he"),
  72. )
  73. ],
  74. )
  75. ),
  76. Hash.new(
  77. :call => [Hash.new(:method => "say")],
  78. :self => SString(" world!");
  79. ),
  80. ]
  81. );
  82. #
  83. ## Begin execution
  84. #
  85. var intr = Interpreter();
  86. intr.execute(ast);