PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/experimental/expr/expr_f90.c

https://github.com/nido/debugger
C | 265 lines | 189 code | 34 blank | 42 comment | 69 complexity | 44ce44eee62c378723c7f2420e5418cc MD5 | raw file
  1. /***************************************************
  2. * This file contains routines for lowering simple *
  3. * syntatic constructs into low-level operations *
  4. ***************************************************/
  5. #include "expr_f90.h"
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <assert.h>
  11. /* The following function removes excess whitespace
  12. from a raw input string. It's a bit involved so
  13. just hope to hell that it continues to work.
  14. */
  15. static int
  16. ex_f90_next(const char* s) {
  17. while (*s == ' ') {
  18. s++;
  19. }
  20. return *s;
  21. }
  22. void
  23. ex_f90_trim_input(char* s) {
  24. unsigned int i=0, j=0;
  25. while (s[j] != '\0') {
  26. /* protect double quote strings */
  27. if (s[j] == '"') {
  28. s[i] = s[j]; i++; j++;
  29. while (s[j] != '\0') {
  30. if (s[j] == '"') {
  31. s[i] = s[j];
  32. i++; j++;
  33. if (s[j] != '"') {
  34. if (ex_f90_next(s+j)=='"') {
  35. printf("syntax error\n");
  36. /*XXX: do real error */
  37. exit(1);
  38. }
  39. break;
  40. }
  41. }
  42. s[i] = s[j];
  43. i++; j++;
  44. }
  45. continue;
  46. }
  47. /* protect single quote strings */
  48. if (s[j] == '\'') {
  49. s[i] = s[j]; i++; j++;
  50. while (s[j] != '\0') {
  51. if (s[j] == '\'') {
  52. s[i] = s[j];
  53. i++; j++;
  54. if (s[j] != '\'') {
  55. if (ex_f90_next(s+j)=='\'') {
  56. printf("syntax error\n");
  57. /*XXX: do real error */
  58. exit(1);
  59. }
  60. break;
  61. }
  62. }
  63. s[i] = s[j];
  64. i++; j++;
  65. }
  66. continue;
  67. }
  68. /* scan through whitespace */
  69. if ( s[j] == ' ' ) {
  70. j++; continue;
  71. }
  72. /* default does literal */
  73. s[i] = s[j];
  74. i++; j++;
  75. }
  76. s[i] = '\0';
  77. }
  78. /* The following function makes a string, either
  79. single or double quoted depending on the second
  80. argument
  81. */
  82. ex_node_t*
  83. ex_f90_new_str(const char* s, int is_single) {
  84. char cpy[strlen(s)+1];
  85. unsigned int i,j;
  86. i = 0; j = 0;
  87. if (is_single) {
  88. while (s[i] != '\0') {
  89. if (s[i] == '\'') {
  90. cpy[j] = '\'';
  91. i++;
  92. } else {
  93. cpy[j] = s[i];
  94. }
  95. i++; j++;
  96. }
  97. } else {
  98. while (s[i] != '\0') {
  99. if (s[i] == '"') {
  100. cpy[j] = '"';
  101. i++;
  102. } else {
  103. cpy[j] = s[i];
  104. }
  105. i++; j++;
  106. }
  107. }
  108. cpy[j] = '\0';
  109. return ex_new_str(cpy, j);
  110. }
  111. /* The following function takes a fortran-style
  112. floating point constant and returns a node
  113. */
  114. ex_node_t*
  115. ex_f90_new_float(const char* s, int go_big) {
  116. char cpy[strlen(s)+1];
  117. unsigned is_doubl = 0;
  118. unsigned int i = 0;
  119. while (s[i] != '\0') {
  120. if (s[i] == 'd' || s[i] == 'D') {
  121. is_doubl = 1;
  122. cpy[i] = 'e';
  123. } else {
  124. cpy[i] = s[i];
  125. }
  126. i++;
  127. }
  128. cpy[i] = '\0';
  129. if (go_big) {
  130. return ex_parse_ldoubl(cpy);
  131. } else if (is_doubl) {
  132. return ex_parse_doubl(cpy);
  133. }
  134. return ex_parse_float(cpy);
  135. }
  136. /* The following function takes a fortran-style
  137. BOZ integer constant and returns a node
  138. */
  139. ex_node_t*
  140. ex_f90_new_integ(const char* s, int base, int sgn) {
  141. char cpy[strlen(s)+1];
  142. unsigned int i, j;
  143. i = 1; j = 0;
  144. while (s[i] != '\'' && s[i] != '"') {
  145. i++;
  146. }
  147. i++;
  148. while (s[i] != '\'' && s[i] != '"') {
  149. cpy[j] = s[i];
  150. i++; j++;
  151. }
  152. cpy[j] = '\0';
  153. return ex_parse_long(cpy, base, sgn);
  154. }
  155. /* The following function makes a named cast node
  156. */
  157. ex_node_t*
  158. ex_f90_kind_cast(ex_node_t* typ, ex_node_t* lit) {
  159. ex_node_t* ret;
  160. ret = ex_new_op1(EX_OP_KINDOF, typ);
  161. ret = ex_new_op2(EX_OP_CVT_KND, ret, lit);
  162. return ret;
  163. }
  164. /* The following function puts together a range
  165. */
  166. ex_node_t*
  167. ex_f90_do_range(
  168. ex_node_t* lo,
  169. ex_node_t* hi,
  170. ex_node_t* inc) {
  171. /* make void for one sided ops */
  172. if (hi == NULL) {
  173. hi = ex_new_op0(EX_OP_VOID);
  174. }
  175. if (lo == NULL) {
  176. lo = ex_new_op0(EX_OP_VOID);
  177. }
  178. /* put together the range node */
  179. if (inc == NULL) {
  180. return ex_new_op2(EX_OP_REF_RNGE,lo,hi);
  181. } else {
  182. return ex_new_op3(EX_OP_REF_RNGE,lo,hi,inc);
  183. }
  184. }
  185. /* The following function checks for illegal constructs
  186. which are parsed for sole purpose of delivering a
  187. more intelligent message later on.
  188. */
  189. void
  190. ex_f90_chk_syntax(ex_node_t* a) {
  191. /* recurse through all children */
  192. EX_FOR_KIDS(a, ex_f90_chk_syntax);
  193. /* check for A**-B type expressions */
  194. if (EX_ND_TYPE(a) == EX_TP_OPER &&
  195. EX_OP_TYPE(a) == EX_OP_ART_POW) {
  196. ex_node_t* kid = EX_KID1(a);
  197. if (EX_ND_TYPE(kid) == EX_TP_OPER && (
  198. EX_OP_TYPE(kid) == EX_OP_SGN_NEG ||
  199. EX_OP_TYPE(kid) == EX_OP_SGN_POS)) {
  200. /* XXX: replace with messaging sytem */
  201. printf("error: expressions of the type A**-B "
  202. "are not standard compliant\n");
  203. printf("error: this form is not consistently "
  204. "evaluated across compilers\n");
  205. exit(1);
  206. }
  207. }
  208. /* check for untyped kind suffices */
  209. if (EX_ND_TYPE(a) == EX_TP_OPER &&
  210. EX_OP_TYPE(a) == EX_OP_CVT_KND) {
  211. ex_node_t* kid0 = EX_KID0(a);
  212. ex_node_t* kid1 = EX_KID1(a);
  213. /* check for untyped kind argument */
  214. if (EX_ND_TYPE(kid0) == EX_TP_OPER &&
  215. EX_OP_TYPE(kid0) == EX_OP_KST_DATA) {
  216. /* XXX: replace with messaging system */
  217. printf("error: kind parameter must be "
  218. "integer or constant variable\n");
  219. exit(1);
  220. }
  221. /* check for untyped constant value */
  222. if (EX_ND_TYPE(kid1) == EX_TP_OPER &&
  223. EX_OP_TYPE(kid1) == EX_OP_KST_DATA) {
  224. /* XXX: replace with messaging system */
  225. printf("error: kind parameter not allowed "
  226. "with untyped constant values\n");
  227. exit(1);
  228. }
  229. }
  230. }