The Sol Programming Language!
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
4.1 KiB

  1. %{
  2. #define YYSTYPE void *
  3. #include "ast.h"
  4. #include "parser.tab.h"
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdio.h>
  8. void yyerror(YYLTYPE *, char *);
  9. int yywrap(void);
  10. char *str, *curptr;
  11. int cursz, chars;
  12. #define SZMUL 128
  13. void str_init(void) {
  14. str = malloc(SZMUL);
  15. curptr = str;
  16. cursz = SZMUL;
  17. chars = 0;
  18. }
  19. void str_putc(char c) {
  20. *curptr++ = c;
  21. chars++;
  22. if(chars >= cursz) {
  23. str = realloc(str, cursz + SZMUL);
  24. curptr = str + chars;
  25. cursz += SZMUL;
  26. }
  27. }
  28. /* http://stackoverflow.com/questions/656703/how-does-flex-support-bison-location-exactly */
  29. /* Many thanks to hugomg and David Elson! */
  30. static void update_loc(YYLTYPE *yylloc, char *yytext){
  31. static int curr_line = 1;
  32. static int curr_col = 1;
  33. yylloc->first_line = curr_line;
  34. yylloc->first_column = curr_col;
  35. {char * s; for(s = yytext; *s != '\0'; s++){
  36. if(*s == '\n'){
  37. curr_line++;
  38. curr_col = 1;
  39. }else{
  40. curr_col++;
  41. }
  42. }}
  43. yylloc->last_line = curr_line;
  44. yylloc->last_column = curr_col-1;
  45. }
  46. #define YY_USER_ACTION update_loc(yylloc, yytext);
  47. %}
  48. DIGIT [0-9]
  49. HEXDIGIT [0-9a-fA-F]
  50. ALPHA [a-zA-Z]
  51. IDENT [a-zA-Z_][a-zA-Z0-9_]*
  52. /* This is the right way to do it, but it keeps generating token $undefined.
  53. %x STRING
  54. \" { str_init(); BEGIN STRING; }
  55. <STRING>\\n { str_putc('\n'); }
  56. <STRING>\\t { str_putc('\t'); }
  57. <STRING>\\b { str_putc('\b'); }
  58. <STRING>\\r { str_putc('\r'); }
  59. <STRING>\\x{HEXDIGIT}{HEXDIGIT} { str_putc(strtol(yytext+2, NULL, 16)); }
  60. <STRING>\\\" { str_putc('"'); }
  61. <STRING>\" { str_putc('\0'); yylval = str; BEGIN 0; return STRING; }
  62. <STRING>. { str_putc(*yytext); }
  63. */
  64. %option bison-bridge bison-locations
  65. %%
  66. {DIGIT}+"."{DIGIT}* { *yylval = malloc(sizeof(double)); *((double *) *yylval) = atof(yytext); return FLOAT; }
  67. {DIGIT}+ { *yylval = malloc(sizeof(long)); *((long *) *yylval) = atol(yytext); return INT; }
  68. \"[^"]*\" { *yylval = strdup(yytext+1); ((char *) *yylval)[yyleng-2] = 0; return STRING; }
  69. \'[^']*\' { *yylval = strdup(yytext+1); ((char *) *yylval)[yyleng-2] = 0; return STRING; }
  70. if { return IF; }
  71. then { return THEN; }
  72. else { return ELSE; }
  73. while { return WHILE; }
  74. for { return FOR; }
  75. in { return IN; }
  76. do { return DO; }
  77. func { return FUNC; }
  78. lambda { return LAMBDA; }
  79. return { return RETURN; }
  80. break { return BREAK; }
  81. continue { return CONTINUE; }
  82. end { return END; }
  83. None { return NONE; }
  84. "+" { return PLUS; }
  85. "-" { return MINUS; }
  86. "*" { return STAR; }
  87. "/" { return SLASH; }
  88. "%" { return PERCENT; }
  89. "**" { return DSTAR; }
  90. "&" { return BAND; }
  91. "|" { return BOR; }
  92. "^" { return BXOR; }
  93. "~" { return BNOT; }
  94. "&&" { return LAND; }
  95. "||" { return LOR; }
  96. "!" { return LNOT; }
  97. "=" { return ASSIGN; }
  98. "+=" { return ASSIGNPLUS; }
  99. "-=" { return ASSIGNMINUS; }
  100. "*=" { return ASSIGNSTAR; }
  101. "/=" { return ASSIGNSLASH; }
  102. "**=" { return ASSIGNDSTAR; }
  103. "&=" { return ASSIGNBAND; }
  104. "|=" { return ASSIGNBOR; }
  105. "^=" { return ASSIGNBXOR; }
  106. "==" { return EQUAL; }
  107. "!=" { return NEQUAL; }
  108. "<" { return LESS; }
  109. ">" { return GREATER; }
  110. "<=" { return LESSEQ; }
  111. ">=" { return GREATEREQ; }
  112. ">>" { return RSHIFT; }
  113. "<<" { return LSHIFT; }
  114. "{" { return LBRACE; }
  115. "}" { return RBRACE; }
  116. "[" { return LBRACKET; }
  117. "]" { return RBRACKET; }
  118. "(" { return LPAREN; }
  119. ")" { return RPAREN; }
  120. "." { return DOT; }
  121. ":" { return COLON; }
  122. ";" { return SEMICOLON; }
  123. "," { return COMMA; }
  124. "#" { return POUND; }
  125. {IDENT} { *yylval = (void *) strdup(yytext); return IDENT; }
  126. --[^\n]*\n /* Skip comments */
  127. [ \t\n]+ /* Skip whitespace */
  128. %%
  129. int yywrap(void) {
  130. return 1;
  131. }
  132. void yyerror(YYLTYPE *locp, char *err) {
  133. puts(err);
  134. printf("(at lines %d-%d, cols %d-%d)\n", locp->first_line, locp->last_line, locp->first_column, locp->last_column);
  135. }
  136. stmt_node *sol_compile(const char *prgstr) {
  137. stmt_node *program = NULL;
  138. YY_BUFFER_STATE buf = yy_scan_string(prgstr);
  139. yyparse(&program);
  140. yy_delete_buffer(buf);
  141. return program;
  142. }
  143. stmt_node *sol_compile_file(FILE *prgfile) {
  144. stmt_node *program = NULL;
  145. YY_BUFFER_STATE buf = yy_create_buffer(prgfile, YY_BUF_SIZE);
  146. yy_switch_to_buffer(buf);
  147. yyparse(&program);
  148. yy_delete_buffer(buf);
  149. return program;
  150. }