p2  0.0
 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 "p2.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:214
#define PN_NUM(i)
Definition: potion.h:213

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:278
#define PN_S(S, N)
Definition: ast.h:33
#define AS_STR(x)
Definition: potion.h:249
#define DBG_c(...)
Definition: potion.h:266
#define PN_SRC(S)
Definition: ast.h:30
#define PN_IS_NIL(v)
Definition: potion.h:169
#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:336
#define PN_TUPLE_EACH(T, I, V, B)
Definition: potion.h:288

Definition at line 201 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:275
#define AS_STR(x)
Definition: potion.h:249
#define DBG_c(...)
Definition: potion.h:266
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:454
#define PN_GET(T, X)
Definition: potion.h:274
#define PN_ASM2(ins, _a, _b)
Definition: compile.c:27
#define potion_send(RCV, MSG, ARGS...)
method caches (more great stuff from ian piumarta)
Definition: potion.h:781
volatile _PN PN
Definition: potion.h:81
#define PN_TUPLE_EACH(T, I, V, B)
Definition: potion.h:288

Definition at line 213 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 AS_STR(x)
Definition: potion.h:249
#define PN_PUSH(T, X)
Definition: potion.h:272
#define DBG_c(...)
Definition: potion.h:266
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:454
#define PN_GET(T, X)
Definition: potion.h:274
#define PN_IS_PROTO(v)
Definition: potion.h:178
const char * name
Definition: compile.c:30
#define vPN(t)
Definition: buffile.c:34

Definition at line 225 of file compile.c.

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

Definition at line 255 of file compile.c.

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

Definition at line 256 of file compile.c.

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

Definition at line 257 of file compile.c.

#define MAX_JUMPS   1024

Definition at line 271 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
PN sig
argument signature
Definition: potion.h:457
#define PN_PUT(T, X)
Definition: potion.h:275
#define PN_PUSH(T, X)
Definition: potion.h:272
#define DBG_c(...)
Definition: potion.h:266
#define SRC_TUPLE_AT(src, i)
Definition: compile.c:256
const char * name
Definition: compile.c:30
#define vPN(t)
Definition: buffile.c:34
#define PN_NIL
Definition: potion.h:139
#define PN_STR_PTR(x)
Definition: potion.h:222

Definition at line 1013 of file compile.c.

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

Definition at line 1223 of file compile.c.

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

Definition at line 1224 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:168
#define PN_STRN(x, l)
Definition: potion.h:220
volatile _PN PN
Definition: potion.h:81
#define READ_PN(pn, ptr)
Definition: compile.c:1224

Definition at line 1225 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:1223
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 1241 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:278
#define READ_TUPLE(ptr)
Definition: compile.c:1241
#define READ_CONST(pn, ptr)
Definition: compile.c:1225

Definition at line 1245 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:278
PN potion_proto_load(Potion *P, PN up, u8 pn, u8 **ptr)
Definition: compile.c:1255
#define READ_TUPLE(ptr)
Definition: compile.c:1241
volatile _PN PN
Definition: potion.h:81

Definition at line 1249 of file compile.c.

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

Definition at line 1300 of file compile.c.

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

Definition at line 1301 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:175
PN potion_num_string(Potion *, PN, PN)
#define WRITE_PN(pn, ptr)
Definition: compile.c:1301
#define PN_STR_LEN(x)
Definition: potion.h:223
#define PN_MEMCPY_N(X, Y, T, N)
Definition: internal.h:22
#define PN_IS_DBL(v)
Definition: potion.h:172
#define PN_IS_PTR(v)
Definition: potion.h:168
volatile _PN PN
Definition: potion.h:81
#define PN_NIL
Definition: potion.h:139
#define PN_STR_PTR(x)
Definition: potion.h:222

Definition at line 1302 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:277
#define WRITE_U8(un, ptr)
Definition: compile.c:1300

Definition at line 1319 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:278
#define WRITE_TUPLE(tup, ptr)
Definition: compile.c:1319
#define WRITE_CONST(val, ptr)
Definition: compile.c:1302

Definition at line 1323 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:278
#define WRITE_TUPLE(tup, ptr)
Definition: compile.c:1319
long potion_proto_dumpbc(Potion *P, PN proto, PN out, long pos)
Definition: compile.c:1337
#define PN_STR_PTR(x)
Definition: potion.h:222

Definition at line 1326 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 260 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 336 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 284 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 1044 of file compile.c.

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

Definition at line 1255 of file compile.c.

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

Definition at line 1399 of file compile.c.

PN potion_eval ( Potion P,
PN  bytes 
)

Definition at line 1415 of file compile.c.

void potion_compiler_init ( Potion P)

Definition at line 1424 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}
}