fork download
  1. #include <string>
  2. #include <stack>
  3. #include <map>
  4. #include <iostream>
  5.  
  6. typedef long val_t;
  7. typedef std::map<std::string, val_t> frame_t;
  8. typedef std::stack<frame_t> stack_t;
  9.  
  10. stack_t stack;
  11. frame_t globals;
  12.  
  13. val_t NOWHERE, arg1_tmp, arg2_tmp, arg3_tmp, result_tmp;
  14.  
  15. #define BEGIN_FUNCTION(name) \
  16.   goto end##name; \
  17.   name: ;
  18.  
  19. #define END_FUNCTION(name) \
  20.   RETURN(0); \
  21.   end##name: ;
  22.  
  23. #define FRAME (stack.top())
  24. #define LOCAL(name) (FRAME[#name])
  25. #define GLOBAL(name) (globals[#name])
  26. #define SPEC(name) (FRAME[":" #name])
  27. #define ARG1 SPEC(ARG1)
  28. #define ARG2 SPEC(ARG2)
  29. #define ARG3 SPEC(ARG3)
  30. #define _RET SPEC(RET)
  31. #define _RES SPEC(RES)
  32.  
  33. #define RETURN(val) \
  34.   do { \
  35.   _RES = val; \
  36.   goto *(void*)_RET; \
  37.   } while(0);
  38.  
  39. #define CALL_START stack.push(frame_t())
  40.  
  41. #define CONCAT(x,y) x##y
  42.  
  43. #define CALL_END(name, uniqueid) \
  44.   _RET = (val_t) &&CONCAT(here, uniqueid); \
  45.   goto name; \
  46.   CONCAT(here, uniqueid): ;
  47.  
  48. #define PUT_RESULT(where) \
  49.   result_tmp = _RES; \
  50.   stack.pop(); \
  51.   where = result_tmp;
  52.  
  53. #define CALL0(func, out) \
  54.   CALL_START; \
  55.   CALL_END(func, __LINE__); \
  56.   PUT_RESULT(out);
  57.  
  58. #define CALL1(func, arg, out) \
  59.   arg1_tmp = arg; \
  60.   CALL_START; \
  61.   ARG1 = arg1_tmp; \
  62.   CALL_END(func, __LINE__); \
  63.   PUT_RESULT(out);
  64.  
  65. #define CALL2(func, arg1, arg2, out) \
  66.   arg1_tmp = arg1; \
  67.   arg2_tmp = arg2; \
  68.   CALL_START; \
  69.   ARG1 = arg1_tmp; \
  70.   ARG2 = arg2_tmp; \
  71.   CALL_END(func, __LINE__); \
  72.   PUT_RESULT(out);
  73.  
  74. #define CALL3(func, arg1, arg2, arg3, out) \
  75.   arg1_tmp = arg1; \
  76.   arg2_tmp = arg2; \
  77.   arg3_tmp = arg3; \
  78.   CALL_START; \
  79.   ARG1 = arg1_tmp; \
  80.   ARG2 = arg2_tmp; \
  81.   ARG3 = arg3_tmp; \
  82.   CALL_END(func, __LINE__); \
  83.   PUT_RESULT(out);
  84.  
  85. int main() {
  86.  
  87. BEGIN_FUNCTION(fac);
  88. LOCAL(f) = 1;
  89. while(ARG1 > 0) {
  90. LOCAL(f) *= ARG1--;
  91. }
  92. RETURN(LOCAL(f));
  93. END_FUNCTION(fac);
  94.  
  95. BEGIN_FUNCTION(fibs);
  96. if(ARG1 <= 0) RETURN(0);
  97. if(ARG1 == 1) RETURN(1);
  98.  
  99. CALL1(fibs, ARG1 - 1, LOCAL(n1));
  100. CALL1(fibs, ARG1 - 2, LOCAL(n2));
  101. RETURN(LOCAL(n1) + LOCAL(n2));
  102. END_FUNCTION(fibs);
  103.  
  104. CALL1(fac, 5, GLOBAL(fac5));
  105. CALL1(fibs, 10, GLOBAL(fibs10));
  106.  
  107. BEGIN_FUNCTION(print);
  108. std::cout << "VALUE: " << ARG1 << std::endl;
  109. END_FUNCTION(print);
  110.  
  111. BEGIN_FUNCTION(print_a);
  112. std::cout << "A: " << GLOBAL(a) << std::endl;
  113. END_FUNCTION(print_a);
  114.  
  115. CALL1(print, GLOBAL(fac5), NOWHERE); // 120
  116. GLOBAL(a) = GLOBAL(fibs10); // 55
  117. CALL0(print_a, NOWHERE);
  118.  
  119. }
  120.  
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
VALUE: 120
A: 55