potion  0.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ast.c
Go to the documentation of this file.
1 //
4 // (c) 2008 why the lucky stiff, the freelance professor
5 //
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include "potion.h"
9 #include "internal.h"
10 #include "ast.h"
11 
13 const char *potion_ast_names[] = {
14  "code", "value", "assign", "not", "or", "and", "cmp", "eq", "neq",
15  "gt", "gte", "lt", "lte", "pipe", "caret", "amp", "wavy", "bitl",
16  "bitr", "plus", "minus", "inc", "times", "div", "rem", "pow",
17  "msg", "path", "query", "pathq", "expr", "list", "block", "lick",
18  "proto", "debug"
19 };
20 
21 const int potion_ast_sizes[] = {
22  1, 3, 2, 1, 2, 2, 2, 2, 2,
23  2, 2, 2, 2, 2, 2, 2, 1, 2,
24  2, 2, 2, 2, 2, 2, 2, 2,
25  3, 1, 1, 1, 1, 1, 1, 3,
26  2, 3
27 };
28 
35 PN potion_source(Potion *P, u8 p, PN a, PN b, PN c, int lineno, PN line) {
36  int size = potion_ast_sizes[p];
37  // TODO: potion_ast_sizes[p] * sizeof(PN) (then fix gc_copy)
38  vPN(Source) t = PN_ALLOC_N(PN_TSOURCE, struct PNSource, 0 * sizeof(PN));
39  t->part = (enum PN_AST)p;
40  t->loc.fileno = P->fileno; // only advanced by load/require
41  t->loc.lineno = lineno;
42  t->line = line;
43 #if 1
44  switch (size) {
45  case 3: t->a[2] = PN_SRC(c);
46  case 2: t->a[1] = PN_SRC(b);
47  case 1: t->a[0] = PN_SRC(a); break;
48  default: potion_fatal("invalid AST type");
49  }
50 #else
51  switch (size) {
52  case 3: t->a[0] = PN_SRC(a); t->a[1] = PN_SRC(b); t->a[2] = PN_SRC(c); break;
53  case 2: t->a[0] = PN_SRC(a); t->a[1] = PN_SRC(b); t->a[2] = 0; break;
54  case 1: t->a[0] = PN_SRC(a); t->a[1] = t->a[2] = 0; break;
55  default: potion_fatal("invalid AST type");
56  }
57 #endif
58  return (PN)t;
59 }
60 
64 static PN potion_source_size(Potion *P, PN cl, PN self) {
65  vPN(Source) t = (struct PNSource *)potion_fwd(self);
66  return PN_NUM(potion_ast_sizes[t->part]);
67 }
68 
71 static PN potion_source_name(Potion *P, PN cl, PN self) {
72  vPN(Source) t = (struct PNSource *)potion_fwd(self);
73  return potion_str(P, potion_ast_names[t->part]);
74 }
75 
79 static PN potion_source_file(Potion *P, PN cl, PN self) {
80  vPN(Source) t = (struct PNSource *)potion_fwd(self);
81  return PN_TUPLE_AT(pn_filenames, t->loc.fileno);
82 }
83 
87 static PN potion_source_lineno(Potion *P, PN cl, PN self) {
88  vPN(Source) t = (struct PNSource *)potion_fwd(self);
89  return PN_NUM(t->loc.lineno);
90 }
91 
95 static PN potion_source_line(Potion *P, PN cl, PN self) {
96  vPN(Source) t = (struct PNSource *)potion_fwd(self);
97  return t->line;
98 }
99 
103 static PN potion_source_string(Potion *P, PN cl, PN self) {
104  int i, n, cut = 0;
105  vPN(Source) t = (struct PNSource *)potion_fwd(self);
106  PN out = potion_byte_str(P, potion_ast_names[t->part]);
107  int lineno = t->loc.lineno;
108  n = potion_ast_sizes[t->part];
109  for (i = 0; i < n; i++) {
110  pn_printf(P, out, " ");
111  if (i == 0 && n > 1) pn_printf(P, out, "(");
112  else if (i > 0) {
113  if (!t->a[i]) { // omit subsequent nils
114  if (!cut) cut = PN_STR_LEN(out);
115  }
116  else cut = 0;
117  }
118  if (PN_IS_STR(t->a[i])) {
119  pn_printf(P, out, "\"");
120  potion_bytes_obj_string(P, out, (PN)t->a[i]);
121  pn_printf(P, out, "\"");
122  } else {
123  potion_bytes_obj_string(P, out, (PN)t->a[i]);
124  }
125  if ((PN_TYPE(t->a[i]) == PN_TSOURCE) && (t->a[i]->loc.lineno > lineno)) {
126  pn_printf(P, out, "\n");
127  lineno = t->a[i]->loc.lineno;
128  }
129  if (i == n - 1 && n > 1) {
130  if (cut > 0) {
131  vPN(Bytes) b = (struct PNBytes *)potion_fwd(out);
132  //DBG_vt("cut at %d, len=%d: \"%s\"\n", cut, b->len, b->chars);
133  if (cut < b->len) {
134  b->len = cut - 1;
135  if (b->chars[cut-1] == ' ')
136  b->chars[cut-1] = '\0';
137  else
138  b->chars[cut] = '\0';
139  }
140  }
141  pn_printf(P, out, ")");
142  }
143  }
144  return PN_STR_B(out);
145 }
146 
149 static PN potion_source_loc(Potion *P, PN cl, PN self) {
150  PN out = potion_byte_str(P, "");
151  pn_printf(P, out, "%s:%ld",
152  PN_STR_PTR(potion_source_file(P, cl, self)),
153  PN_INT(potion_source_lineno(P, cl, self)));
154  return PN_STR_B(out);
155 }
156 
158  PN src_vt = PN_VTABLE(PN_TSOURCE);
159  potion_method(src_vt, "name", potion_source_name, 0);
160  potion_method(src_vt, "string", potion_source_string, 0);
161  potion_method(src_vt, "size", potion_source_size, 0);
162  potion_method(src_vt, "file", potion_source_file, 0);
163  potion_method(src_vt, "lineno", potion_source_lineno, 0);
164  potion_method(src_vt, "line", potion_source_line, 0);
165  potion_method(src_vt, "loc", potion_source_loc, 0);
166 }
#define PN_TUPLE_AT(t, n)
Definition: potion.h:269
static PN potion_source_line(Potion *P, PN cl, PN self)
Definition: ast.c:95
#define PN_IS_STR(v)
Definition: potion.h:166
PN_AST
An AST fragment, non-volatile.
Definition: potion.h:386
PN potion_str(Potion *, const char *)
Definition: string.c:33
byte strings are raw character data, volatile, may be appended/changed.
Definition: potion.h:338
#define vPN(t)
Definition: potion.h:132
PN pn_filenames
Definition: internal.c:23
#define PN_ALLOC_N(V, T, C)
Definition: internal.h:13
PN_SIZE void potion_bytes_obj_string(Potion *, PN, PN)
Definition: string.c:384
PN PN potion_byte_str(Potion *, const char *)
Definition: string.c:331
#define potion_method(RCV, MSG, FN, SIG)
Definition: potion.h:780
#define PN_STR_LEN(x)
Definition: potion.h:214
static PN potion_fwd(PN)
the potion type is the 't' in the vtable tuple (m,t)
Definition: potion.h:561
static PN potion_source_file(Potion *P, PN cl, PN self)
Definition: ast.c:79
PN_SIZE fileno
currently parsed file
Definition: potion.h:660
the ast for Potion code in-memory
#define PN_SRC(S)
Definition: ast.h:30
#define PN_INT(x)
Definition: potion.h:205
#define PN_NUM(i)
Definition: potion.h:204
#define PN_STR_B(x)
Definition: potion.h:215
static PN potion_source_loc(Potion *P, PN cl, PN self)
Definition: ast.c:149
const char * potion_ast_names[]
Definition: ast.c:13
#define PN_TSOURCE
Definition: potion.h:120
static PN potion_source_name(Potion *P, PN cl, PN self)
Definition: ast.c:71
PN_SIZE len
Definition: potion.h:340
unsigned char u8
Definition: internal.h:8
static PN potion_source_lineno(Potion *P, PN cl, PN self)
Definition: ast.c:87
PN potion_source(Potion *P, u8 p, PN a, PN b, PN c, int lineno, PN line)
PNSource constructor.
Definition: ast.c:35
non-API internal parts
the global interpreter state P. currently singleton (not threads yet)
Definition: potion.h:644
The potion API.
PN_SIZE pn_printf(Potion *, PN, const char *,...) __attribute__((format(printf
#define PN_TYPE(x)
Definition: potion.h:133
const int potion_ast_sizes[]
Definition: ast.c:21
void potion_source_init(Potion *P)
Definition: ast.c:157
volatile _PN PN
Definition: potion.h:81
PNType lineno
Definition: potion.h:435
static PN potion_source_string(Potion *P, PN cl, PN self)
Definition: ast.c:103
void potion_fatal(char *message)
Definition: internal.c:282
#define PN_STR_PTR(x)
Definition: potion.h:213
#define PN_VTABLE(t)
Definition: potion.h:136
static PN potion_source_size(Potion *P, PN cl, PN self)
Definition: ast.c:64