potion  0.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
compile.c File Reference

transform the ast to simple two-address lua-like bytecode. More...

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include "potion.h"
#include "internal.h"
#include "ast.h"
#include "opcodes.h"
#include "asm.h"
#include <dlfcn.h>
+ Include dependency graph for compile.c:

Go to the source code of this file.

Data Structures

struct  PNLoop
 jump table for loops, for the 2 args b and c Note: only statically allocated (max 1024) More...
 

Macros

#define PN_ASM1(ins, _a)   f->asmb = (PN)potion_asm_op(P, (PNAsm *)f->asmb, (u8)ins, (int)_a, 0)
 
#define PN_ASM2(ins, _a, _b)   f->asmb = (PN)potion_asm_op(P, (PNAsm *)f->asmb, (u8)ins, (int)_a, (int)_b)
 
#define PN_REG(f, reg)
 
#define PN_ARG(n, reg)
 
#define PN_BLOCK(reg, blk, sig)
 
#define PN_UPVAL(name)
 
#define PN_ARG_TABLE(args, reg, inc)   potion_arg_asmb(P, f, loop, args, &reg, inc)
 
#define SRC_TUPLE_AT(src, i)   PN_SRC(PN_TUPLE_AT(PN_S(src,0), i))
 
#define PN_ASM_DEBUG(REG, T)   REG = potion_source_debug(P, f, T, REG)
 
#define MAX_JUMPS   1024
 
#define LOAD_ARG()   PN_ARG_TABLE(PN_S(t,1), breg, 1)
 
#define SIG_EXPR_MSG(name, expr)
 
#define READ_U8(ptr)   ({u8 rpu = *ptr; ptr += sizeof(u8); rpu;})
 
#define READ_PN(pn, ptr)   ({PN rpn = *(PN *)ptr; ptr += pn; rpn;})
 
#define READ_CONST(pn, ptr)
 
#define READ_TUPLE(ptr)
 
#define READ_VALUES(pn, ptr)
 
#define READ_PROTOS(pn, ptr)
 
#define WRITE_U8(un, ptr)   ({*ptr = (u8)un; ptr += sizeof(u8);})
 
#define WRITE_PN(pn, ptr)   ({*(PN *)ptr = pn; ptr += sizeof(PN);})
 
#define WRITE_CONST(val, ptr)
 
#define WRITE_TUPLE(tup, ptr)
 
#define WRITE_VALUES(tup, ptr)
 
#define WRITE_PROTOS(tup, ptr)
 

Functions

PN potion_sig_string (Potion *P, PN cl, PN sig)
 
u8 potion_source_debug (Potion *P, struct PNProto *volatile f, struct PNSource *volatile t, u8 reg)
 insert DEBUG ops for every new line More...
 
void potion_source_asmb (Potion *, struct PNProto *volatile, struct PNLoop *, PN_SIZE, struct PNSource *volatile, u8)
 
void potion_arg_asmb (Potion *P, struct PNProto *volatile f, struct PNLoop *loop, PN args, u8 *reg, int inc)
 
PN potion_sig_compile (Potion *P, vPN(Proto) f, PN src)
 Converts a pre-compiled potion expr to a signature tuple. More...
 
PN potion_proto_load (Potion *P, PN up, u8 pn, u8 **ptr)
 
PN potion_run (Potion *P, PN code, int jit)
 
PN potion_eval (Potion *P, PN bytes)
 
void potion_compiler_init (Potion *P)
 

Variables

struct {
   const char *   name
 
   const u8   args
 
potion_ops []
 

Detailed Description

transform the ast to simple two-address lua-like bytecode.

A full three-address VM with possible SSA form is not needed. This is for highly dynamic languages, and the typed parts can be optimized differently.

implement the PNSource (AST) and PNProto (closure) methods, special signature handling (parsed extra) and compile, bytecode load and dump methods. Some special control methods are handled here and not in the parser. We do not need lexed keywords, and are free to extend everything dynamically.

(c) 2008 why the lucky stiff, the freelance professor (c) 2014 perl11.org

Definition in file compile.c.

Macro Definition Documentation

#define PN_ASM1 (   ins,
  _a 
)    f->asmb = (PN)potion_asm_op(P, (PNAsm *)f->asmb, (u8)ins, (int)_a, 0)

Definition at line 26 of file compile.c.

#define PN_ASM2 (   ins,
  _a,
  _b 
)    f->asmb = (PN)potion_asm_op(P, (PNAsm *)f->asmb, (u8)ins, (int)_a, (int)_b)

Definition at line 27 of file compile.c.

#define PN_REG (   f,
  reg 
)
Value:
if (reg >= PN_INT(f->stack)) \
f->stack = PN_NUM(reg + 1)
#define PN_INT(x)
Definition: potion.h:205
#define PN_NUM(i)
Definition: potion.h:204

Definition at line 184 of file compile.c.

#define PN_ARG (   n,
  reg 
)
Value:
if (PN_PART(t->a[n]) == AST_EXPR && PN_PART(PN_TUPLE_AT(PN_S(t->a[n],0), 0)) == AST_LIST) { \
PN test = PN_S(PN_TUPLE_AT(PN_S(t->a[n],0), 0), 0); \
if (!PN_IS_NIL(test)) { \
DBG_c("expr (list %s) => %s\n", AS_STR(test), AS_STR(test)); \
PN_TUPLE_EACH(test, i, v, { \
potion_source_asmb(P, f, loop, 0, PN_SRC(v), reg); }); \
} \
} else { \
potion_source_asmb(P, f, loop, 0, t->a[n], reg); \
}
#define PN_TUPLE_AT(t, n)
Definition: potion.h:269
#define PN_S(S, N)
Definition: ast.h:33
#define AS_STR(x)
Definition: potion.h:240
#define DBG_c(...)
Definition: potion.h:250
#define PN_SRC(S)
Definition: ast.h:30
#define PN_IS_NIL(v)
Definition: potion.h:160
#define PN_PART(S)
Definition: ast.h:31
volatile _PN PN
Definition: potion.h:81
void potion_source_asmb(Potion *, struct PNProto *volatile, struct PNLoop *, PN_SIZE, struct PNSource *volatile, u8)
Definition: compile.c:321
#define PN_TUPLE_EACH(T, I, V, B)
Definition: potion.h:279

Definition at line 187 of file compile.c.

#define PN_BLOCK (   reg,
  blk,
  sig 
)
Value:
({ \
PN block = potion_send(blk, PN_compile, (PN)f, sig); \
PN_SIZE num = PN_PUT(f->protos, block); \
DBG_c("protos => %u\n", num); \
PN_ASM2(OP_PROTO, reg, num); \
PN_TUPLE_EACH(((struct PNProto *)block)->upvals, i, v, { \
PN_SIZE numup = PN_GET(f->upvals, v); \
DBG_c("upvals %s <= %d\n", AS_STR(v), (int)numup); \
if (numup != PN_NONE) PN_ASM2(OP_GETUPVAL, reg, numup); \
else PN_ASM2(OP_GETLOCAL, reg, PN_GET(f->locals, v)); \
}); \
})
PN PN_compile
Definition: internal.c:14
#define PN_PUT(T, X)
Definition: potion.h:266
#define AS_STR(x)
Definition: potion.h:240
#define DBG_c(...)
Definition: potion.h:250
unsigned int PN_SIZE
Definition: potion.h:79
#define PN_NONE
Definition: potion.h:145
a prototype is compiled source code, a closure block (lambda) non-volatile.
Definition: potion.h:445
#define PN_GET(T, X)
Definition: potion.h:265
#define PN_ASM2(ins, _a, _b)
Definition: compile.c:27
PN sig
signature PNTuple
Definition: potion.h:375
#define potion_send(RCV, MSG, ARGS...)
method caches (more great stuff from ian piumarta)
Definition: potion.h:772
volatile _PN PN
Definition: potion.h:81
#define PN_TUPLE_EACH(T, I, V, B)
Definition: potion.h:279

Definition at line 198 of file compile.c.

#define PN_UPVAL (   name)
Value:
({ \
PN_SIZE numl = PN_GET(f->locals, name); \
DBG_c("locals %s <= %d\n", AS_STR(name), (int)numl); \
PN_SIZE numup = PN_NONE; \
if (numl == PN_NONE) { \
numup = PN_GET(f->upvals, name); \
if (numup == PN_NONE) { \
DBG_c("upvals %s <= -1\n", AS_STR(name)); \
vPN(Proto) up = f; \
int depth = 1; \
while (PN_IS_PROTO(up->source)) { \
up = (struct PNProto *)up->source; \
if (PN_NONE != (numup = PN_GET(up->locals, name))) break; \
depth++; \
} \
DBG_c("locals %s <= %d\n", AS_STR(name), (int)numup); \
if (numup != PN_NONE) { \
up = f; \
while (depth--) { \
up->upvals = PN_PUSH(up->upvals, name); \
DBG_c("upvals %s =>\n", AS_STR(name)); \
up = (struct PNProto *)up->source; \
} \
} \
numup = PN_GET(f->upvals, name); \
DBG_c("upvals %s <= %d\n", AS_STR(name), (int)numup); \
} \
} \
numup; \
})
#define vPN(t)
Definition: potion.h:132
#define AS_STR(x)
Definition: potion.h:240
#define PN_PUSH(T, X)
Definition: potion.h:263
#define DBG_c(...)
Definition: potion.h:250
unsigned int PN_SIZE
Definition: potion.h:79
#define PN_NONE
Definition: potion.h:145
a prototype is compiled source code, a closure block (lambda) non-volatile.
Definition: potion.h:445
#define PN_GET(T, X)
Definition: potion.h:265
#define PN_IS_PROTO(v)
Definition: potion.h:169
const char * name
Definition: compile.c:30

Definition at line 210 of file compile.c.

#define PN_ARG_TABLE (   args,
  reg,
  inc 
)    potion_arg_asmb(P, f, loop, args, &reg, inc)

Definition at line 240 of file compile.c.

#define SRC_TUPLE_AT (   src,
 
)    PN_SRC(PN_TUPLE_AT(PN_S(src,0), i))

Definition at line 241 of file compile.c.

#define PN_ASM_DEBUG (   REG,
 
)    REG = potion_source_debug(P, f, T, REG)

Definition at line 242 of file compile.c.

#define MAX_JUMPS   1024

Definition at line 256 of file compile.c.

#define LOAD_ARG ( )    PN_ARG_TABLE(PN_S(t,1), breg, 1)
#define SIG_EXPR_MSG (   name,
  expr 
)
Value:
if (expr->part == AST_EXPR) { \
vPN(Source) t = SRC_TUPLE_AT(expr, 0); \
if (t->part == AST_MSG) { \
name = PN_S(t,0); \
PN_PUT(f->locals, name); \
DBG_c("locals %s\n", PN_STR_PTR(name)); \
} \
} else { name = PN_NIL; }
#define PN_S(S, N)
Definition: ast.h:33
#define vPN(t)
Definition: potion.h:132
PN sig
argument signature
Definition: potion.h:448
#define PN_PUT(T, X)
Definition: potion.h:266
#define PN_PUSH(T, X)
Definition: potion.h:263
#define DBG_c(...)
Definition: potion.h:250
#define SRC_TUPLE_AT(src, i)
Definition: compile.c:241
const char * name
Definition: compile.c:30
#define PN_NIL
Definition: potion.h:139
#define PN_STR_PTR(x)
Definition: potion.h:213

Definition at line 911 of file compile.c.

#define READ_U8 (   ptr)    ({u8 rpu = *ptr; ptr += sizeof(u8); rpu;})

Definition at line 1107 of file compile.c.

#define READ_PN (   pn,
  ptr 
)    ({PN rpn = *(PN *)ptr; ptr += pn; rpn;})

Definition at line 1108 of file compile.c.

#define READ_CONST (   pn,
  ptr 
)
Value:
({ \
PN val = READ_PN(pn, ptr); \
if (PN_IS_PTR(val)) { \
if (val & 2) { \
size_t len = ((val ^ 2) >> 4) - 1; \
val = potion_strtod(P, (char *)ptr, len); \
ptr += len; \
} else { \
size_t len = (val >> 4) - 1; \
val = PN_STRN((char *)ptr, len); \
ptr += len; \
} \
} \
val; \
})
PN potion_strtod(Potion *P, char *str, int len)
Convert string to double.
Definition: number.c:24
#define PN_IS_PTR(v)
Definition: potion.h:159
#define PN_STRN(x, l)
Definition: potion.h:211
volatile _PN PN
Definition: potion.h:81
#define READ_PN(pn, ptr)
Definition: compile.c:1108

Definition at line 1109 of file compile.c.

#define READ_TUPLE (   ptr)
Value:
long i = 0, count = READ_U8(ptr); \
PN tup = potion_tuple_with_size(P, (PN_SIZE)count); \
for (; i < count; i++)
#define READ_U8(ptr)
Definition: compile.c:1107
unsigned int PN_SIZE
Definition: potion.h:79
volatile _PN PN
Definition: potion.h:81
PN potion_tuple_with_size(Potion *, unsigned long)
Definition: table.c:242

Definition at line 1125 of file compile.c.

#define READ_VALUES (   pn,
  ptr 
)
Value:
({ \
READ_TUPLE(ptr) PN_TUPLE_AT(tup, i) = READ_CONST(pn, ptr); \
tup; \
})
#define PN_TUPLE_AT(t, n)
Definition: potion.h:269
#define READ_TUPLE(ptr)
Definition: compile.c:1125
#define READ_CONST(pn, ptr)
Definition: compile.c:1109

Definition at line 1129 of file compile.c.

#define READ_PROTOS (   pn,
  ptr 
)
Value:
({ \
READ_TUPLE(ptr) PN_TUPLE_AT(tup, i) = potion_proto_load(P, (PN)f, pn, &(ptr)); \
tup; \
})
#define PN_TUPLE_AT(t, n)
Definition: potion.h:269
PN potion_proto_load(Potion *P, PN up, u8 pn, u8 **ptr)
Definition: compile.c:1139
#define READ_TUPLE(ptr)
Definition: compile.c:1125
volatile _PN PN
Definition: potion.h:81

Definition at line 1133 of file compile.c.

#define WRITE_U8 (   un,
  ptr 
)    ({*ptr = (u8)un; ptr += sizeof(u8);})

Definition at line 1184 of file compile.c.

#define WRITE_PN (   pn,
  ptr 
)    ({*(PN *)ptr = pn; ptr += sizeof(PN);})

Definition at line 1185 of file compile.c.

#define WRITE_CONST (   val,
  ptr 
)
Value:
({ \
if (PN_IS_STR(val)) { \
PN count = (PN_STR_LEN(val)+1) << 4; \
WRITE_PN(count, ptr); \
PN_MEMCPY_N(ptr, PN_STR_PTR(val), char, PN_STR_LEN(val)); \
ptr += PN_STR_LEN(val); \
} else if (PN_IS_DBL(val)) { \
PN str = potion_num_string(P, PN_NIL, val); \
PN count = ((PN_STR_LEN(str)+1) << 4) | 2; \
WRITE_PN(count, ptr); \
PN_MEMCPY_N(ptr, PN_STR_PTR(str), char, PN_STR_LEN(str)); \
ptr += PN_STR_LEN(str); \
} else { \
PN cval = (PN_IS_PTR(val) ? PN_NIL : val); \
WRITE_PN(cval, ptr); \
} \
})
#define PN_IS_STR(v)
Definition: potion.h:166
PN potion_num_string(Potion *, PN, PN)
#define WRITE_PN(pn, ptr)
Definition: compile.c:1185
#define PN_STR_LEN(x)
Definition: potion.h:214
#define PN_MEMCPY_N(X, Y, T, N)
Definition: internal.h:22
#define PN_IS_DBL(v)
Definition: potion.h:163
#define PN_IS_PTR(v)
Definition: potion.h:159
volatile _PN PN
Definition: potion.h:81
#define PN_NIL
Definition: potion.h:139
#define PN_STR_PTR(x)
Definition: potion.h:213

Definition at line 1186 of file compile.c.

#define WRITE_TUPLE (   tup,
  ptr 
)
Value:
long i = 0, count = PN_TUPLE_LEN(tup); \
WRITE_U8(count, ptr); \
for (; i < count; i++)
#define PN_TUPLE_LEN(t)
Definition: potion.h:268
#define WRITE_U8(un, ptr)
Definition: compile.c:1184

Definition at line 1203 of file compile.c.

#define WRITE_VALUES (   tup,
  ptr 
)
Value:
({ \
WRITE_TUPLE(tup, ptr) WRITE_CONST(PN_TUPLE_AT(tup, i), ptr); \
})
#define PN_TUPLE_AT(t, n)
Definition: potion.h:269
#define WRITE_TUPLE(tup, ptr)
Definition: compile.c:1203
#define WRITE_CONST(val, ptr)
Definition: compile.c:1186

Definition at line 1207 of file compile.c.

#define WRITE_PROTOS (   tup,
  ptr 
)
Value:
({ \
WRITE_TUPLE(tup, ptr) ptr += potion_proto_dumpbc(P, PN_TUPLE_AT(tup, i), \
out, (char *)ptr - PN_STR_PTR(out)); \
})
#define PN_TUPLE_AT(t, n)
Definition: potion.h:269
#define WRITE_TUPLE(tup, ptr)
Definition: compile.c:1203
long potion_proto_dumpbc(Potion *P, PN proto, PN out, long pos)
Definition: compile.c:1221
#define PN_STR_PTR(x)
Definition: potion.h:213

Definition at line 1210 of file compile.c.

Function Documentation

PN potion_sig_string ( Potion P,
PN  cl,
PN  sig 
)
Returns
string of the sig tuple. "arg1=o,arg2=o"

Definition at line 60 of file compile.c.

u8 potion_source_debug ( Potion P,
struct PNProto *volatile  f,
struct PNSource *volatile  t,
u8  reg 
)

insert DEBUG ops for every new line

Definition at line 245 of file compile.c.

void potion_source_asmb ( Potion P,
struct PNProto * volatile  f,
struct PNLoop loop,
PN_SIZE  count,
struct PNSource * volatile  t,
u8  reg 
)

Definition at line 321 of file compile.c.

void potion_arg_asmb ( Potion P,
struct PNProto *volatile  f,
struct PNLoop loop,
PN  args,
u8 reg,
int  inc 
)

Definition at line 269 of file compile.c.

PN potion_sig_compile ( Potion P,
vPN(Proto)  f,
PN  src 
)

Converts a pre-compiled potion expr to a signature tuple.

Extract locals, apply type defaults and do type and param checks. Sigs are also ambigious, the parser usually compiles it down to expression trees, not to a sig tuple. Converts assign,pipe,value.

Not used by P2, as args2 generates the correct sig tuple in the parser already.

Todo:
this is overly complicated. create tuples as in P2 in the parser, do not reuse expr and assign.

Name=Type, '|' optional '.' end ':='default type: 'o' (= PN object) Encode to 3-tuple AST_CODE: name type|modifier default

Parameters
fthe PNProto closure to store locals
srcPNSource signature tree, parsed via yy_sig()
Returns
PNTuple of sigs

(x=n,y:=1) =>

(list (assign (expr (msg (x)) expr (msg (n ))),
assign (expr (msg (y)) value (1 )))

Definition at line 942 of file compile.c.

PN potion_proto_load ( Potion P,
PN  up,
u8  pn,
u8 **  ptr 
)

Definition at line 1139 of file compile.c.

PN potion_run ( Potion P,
PN  code,
int  jit 
)

Definition at line 1283 of file compile.c.

PN potion_eval ( Potion P,
PN  bytes 
)

Definition at line 1299 of file compile.c.

void potion_compiler_init ( Potion P)

Definition at line 1308 of file compile.c.

Variable Documentation

const char* name

Definition at line 30 of file compile.c.

const u8 args

Definition at line 31 of file compile.c.

const { ... } potion_ops[]
Initial value:
= {
{"noop", 0}, {"move", 2}, {"loadk", 2}, {"loadpn", 2}, {"self", 1},
{"newtuple", 2}, {"gettuple", 2}, {"settuple", 2}, {"getlocal", 2}, {"setlocal", 2},
{"getupval", 2}, {"setupval", 2}, {"global", 2}, {"gettable", 2},
{"settable", 2}, {"newlick", 2}, {"getpath", 2}, {"setpath", 2},
{"add", 2}, {"sub", 2}, {"mult", 2}, {"div", 2}, {"mod", 2}, {"pow", 2},
{"not", 1}, {"cmp", 2}, {"eq", 2}, {"neq", 2}, {"lt", 2}, {"lte", 2},
{"gt", 2}, {"gte", 2}, {"bitn", 2}, {"bitl", 2}, {"bitr", 2}, {"def", 2},
{"bind", 2}, {"msg", 2}, {"jump", 1}, {"test", 2}, {"testjmp", 2},
{"notjmp", 2}, {"named", 2}, {"call", 2}, {"callset", 2}, {"tailcall", 2},
{"return", 1}, {"proto", 2}, {"class", 2}, {"debug", 2}
}