What language is this code? - programming-languages

I wonder what kind of language this code is (if it is even a language).
This was taken out of a machine which prints text on products using lasers, so it's probably some machine code or something: (i got it delivered in a *.lst file)
{
PLACE {
BOX
}
1816 1787 0 3696 0
}
{
PLACE {
BOX
}
1816 1787 0 1760 0
}
{
PLACE {
BOX
}
1816 1787 0 -153 0
}
{
PLACE {
BOX
}
1816 1787 0 -2142 0
}
{
PLACE {
BOX
}
1816 1787 0 -4091 0
}
{
INFO Composition Producten1
}
{
Script {
Producten
}
}
{
INFO Producte1
}
{
Graphic {
}
-9508 0 7377 -5000 0 0
}
{
Graphic {
}
-9590 984 6557 5000 0 0
}
{
Graphic {
}
-9426 -8852 -4153 0 0 0
}
{
Graphic {
}
-9590 -8962 -5628 0 0 0
}
{
Circle_TEXT {
1409
}
542 1192 4552 1279 0 6240 1 DatroFont1 9999 9999
}
{
TEXT {
43
}
17951 2350 5137 5000 5246 5246 DatroFont1 0
}
{
TEXT {
}
-8115 -2787 6407 0 -1967 0 DatroFont1 0
}
{
Circle_TEXT {
500001
}
487 1192 3842 1279 0 6627 0 DatroFont1
}
{
INFO Producte2
}
{
Graphic {
}
-9426 -929 3044 0 0 0
}
{
Graphic {
}
-9590 -8251 6066 0 0 0
}
{
Graphic {
}
-9590 -7322 -4153 0 0 0
}
{
Graphic {
}
-9754 -7486 -5683 0 0 0
}
{
Circle_TEXT {
1409
}
542 1192 4552 1279 0 2835 1 DatroFont1 9999 9999
}
{
TEXT {
}
-8033 -874 3002 0 0 0 DatroFont1 0
}
{
TEXT {
}
-8115 820 3002 0 -1967 0 DatroFont1 0
}
{
Circle_TEXT {
500002
}
487 1192 3842 1279 0 3222 0 DatroFont1
}
{
INFO Producte3
}
{
Graphic {
}
-9426 -929 -415 0 0 0
}
{
Graphic {
}
-9508 -7268 6066 0 0 0
}
{
Graphic {
}
-9426 -6503 -4208 0 0 0
}
{
Graphic {
}
-9672 -6612 -5738 0 0 0
}
{
Circle_TEXT {
1409
}
542 1192 4552 1279 0 -570 1 DatroFont1 9999 9999
}
{
TEXT {
}
-8033 -874 -403 0 0 0 DatroFont1 0
}
{
TEXT {
}
-8115 820 -403 0 -1967 0 DatroFont1 0
}
{
Circle_TEXT {
500003
}
487 1192 3842 1279 0 -183 0 DatroFont1
}
{
INFO Producte4
}
{
Graphic {
}
-9426 -929 -3874 0 0 0
}
{
Graphic {
}
-8934 2842 6066 0 0 0
}
{
Graphic {
}
-8934 2896 -4098 0 0 0
}
{
Graphic {
}
-8934 2842 -5847 0 0 0
}
{
Circle_TEXT {
1409
}
542 1192 4552 1279 0 -3975 1 DatroFont1 9999 9999
}
{
TEXT {
}
-8033 -874 -3808 0 0 0 DatroFont1 0
}
{
TEXT {
}
-8115 820 -3808 0 -1967 0 DatroFont1 0
}
{
Circle_TEXT {
500004
}
487 1192 3842 1279 0 -3588 0 DatroFont1
}
{
INFO Producte5
}
{
Graphic {
}
-9426 -929 -7333 0 0 0
}
{
Graphic {
}
-8934 6175 6066 0 0 0
}
{
Graphic {
}
-8934 6284 -4044 0 0 0
}
{
Graphic {
}
-8934 6284 -6175 0 0 0
}
{
Circle_TEXT {
1409
}
542 1192 4552 1279 0 -7380 1 DatroFont1 9999 9999
}
{
TEXT {
}
-8033 -874 -7213 0 0 0 DatroFont1 0
}
{
TEXT {
}
-8115 820 -7213 0 -1967 0 DatroFont1 0
}
{
Circle_TEXT {
500005
}
487 1192 3842 1279 0 -6993 0 DatroFont1
}
RESTART {
CharacterDistanceOffset 183
}
{
Parameter {
Producttest
}
}
Any ideas?

It is very likely to be Postscript (based on the use of the { and } )

Related

Varnish compiler will not start when providing correct .vcl file

I installed Varnish with command apt-get install varnish
Varnish version is varnishd (varnish-6.2.1 revision 9f8588e4ab785244e06c3446fe09bf9db5dd8753)
I try to validate my VCL file with command varnishd -C -f /etc/varnish/default.vcl
My VCL file:
vcl 4.0;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
}
sub vcl_backend_response {
}
sub vcl_deliver {
}
This is the response I get, seems like it just echoes out varnish .c file:
/* ---===### Location Counters ###===---*/
#define VGC_NREFS 35
static const struct vrt_ref VGC_ref[VGC_NREFS] = {
[ 1] = { 0, 796, 26, 1, "}" },
[ 2] = { 0, 1025, 33, 1, "}" },
[ 3] = { 0, 1223, 40, 1, "}" },
[ 4] = { 1, 1605, 38, 5, "if" },
[ 5] = { 1, 1719, 40, 9, "return" },
[ 6] = { 1, 1750, 42, 5, "if" },
[ 7] = { 1, 1890, 46, 9, "return" },
[ 8] = { 1, 1921, 48, 5, "if" },
[ 9] = { 1, 2225, 57, 9, "return" },
[ 10] = { 1, 2251, 60, 5, "if" },
[ 11] = { 1, 2366, 62, 9, "return" },
[ 12] = { 1, 2391, 64, 5, "if" },
[ 13] = { 1, 2487, 66, 9, "return" },
[ 14] = { 1, 2512, 68, 5, "return" },
[ 15] = { 1, 2819, 77, 5, "return" },
[ 16] = { 1, 2856, 81, 5, "return" },
[ 17] = { 1, 2894, 85, 5, "hash_data" },
[ 18] = { 1, 2947, 87, 9, "hash_data" },
[ 19] = { 1, 2994, 89, 9, "hash_data" },
[ 20] = { 1, 3066, 95, 5, "return" },
[ 21] = { 1, 3118, 99, 5, "return" },
[ 22] = { 1, 3158, 103, 5, "return" },
[ 23] = { 1, 3199, 107, 5, "return" },
[ 24] = { 1, 3316, 114, 5, "set" },
[ 25] = { 1, 3907, 138, 5, "if" },
[ 26] = { 1, 3944, 139, 9, "unset" },
[ 27] = { 1, 3972, 141, 5, "return" },
[ 28] = { 1, 4022, 145, 5, "if" },
[ 29] = { 1, 4055, 146, 9, "return" },
[ 30] = { 1, 4407, 154, 9, "set" },
[ 31] = { 1, 4479, 157, 5, "return" },
[ 32] = { 1, 4528, 161, 5, "set" },
[ 33] = { 1, 5127, 185, 5, "return" },
[ 34] = { 1, 5162, 189, 5, "return" },
};
/* ---===### VCC generated .h code ###===---*/
static struct vsmw_cluster *vsc_cluster;
extern const struct VCL_conf VCL_conf;
static VCL_BACKEND vgc_backend_default;
/* "127.0.0.1 8080" -> 127.0.0.1 */
static const unsigned long long suckaddr_0[4] = {
0x901f00024b1e9335ULL,
0x000000000100007fULL,
0x0000000000000000ULL,
0x0000000000000000ULL
};
static const struct vrt_backend vgc_dir_priv_vgc_backend_default = {
.magic = VRT_BACKEND_MAGIC,
.vcl_name = "default",
.ipv4_suckaddr = (const struct suckaddr *)(const void*)suckaddr_0,
.ipv4_addr = "127.0.0.1",
.port = "8080",
.path = (void *) 0,
.hosthdr = "127.0.0.1",
};
static const struct gethdr_s VGC_HDR_REQ_host =
{ HDR_REQ, "\005host:"};
static void *VGC_re_1;
static const struct gethdr_s VGC_HDR_REQ_Authorization =
{ HDR_REQ, "\016Authorization:"};
static const struct gethdr_s VGC_HDR_REQ_Cookie =
{ HDR_REQ, "\007Cookie:"};
static const struct gethdr_s VGC_HDR_RESP_Content_2d_Type =
{ HDR_RESP, "\015Content-Type:"};
static const struct gethdr_s VGC_HDR_RESP_Retry_2d_After =
{ HDR_RESP, "\014Retry-After:"};
static const struct gethdr_s VGC_HDR_BERESP_Set_2d_Cookie =
{ HDR_BERESP, "\013Set-Cookie:"};
static const struct gethdr_s VGC_HDR_BERESP_Surrogate_2d_control =
{ HDR_BERESP, "\022Surrogate-control:"};
static void *VGC_re_2;
static const struct gethdr_s VGC_HDR_BERESP_Cache_2d_Control =
{ HDR_BERESP, "\016Cache-Control:"};
static void *VGC_re_3;
static const struct gethdr_s VGC_HDR_BERESP_Vary =
{ HDR_BERESP, "\005Vary:"};
static const struct gethdr_s VGC_HDR_BERESP_Content_2d_Type =
{ HDR_BERESP, "\015Content-Type:"};
static const struct gethdr_s VGC_HDR_BERESP_Retry_2d_After =
{ HDR_BERESP, "\014Retry-After:"};
vcl_func_f VGC_function_vcl_backend_error;
vcl_func_f VGC_function_vcl_backend_fetch;
vcl_func_f VGC_function_vcl_backend_response;
vcl_func_f VGC_function_vcl_deliver;
vcl_func_f VGC_function_vcl_fini;
vcl_func_f VGC_function_vcl_hash;
vcl_func_f VGC_function_vcl_hit;
vcl_func_f VGC_function_vcl_init;
vcl_func_f VGC_function_vcl_miss;
vcl_func_f VGC_function_vcl_pass;
vcl_func_f VGC_function_vcl_pipe;
vcl_func_f VGC_function_vcl_purge;
vcl_func_f VGC_function_vcl_recv;
vcl_func_f VGC_function_vcl_synth;
static unsigned vgc_inistep;
static unsigned vgc_warmupstep;
/* ---===### VCC generated .c code ###===---*/
#define END_ if (*ctx->handling) return
void v_matchproto_(vcl_func_f)
VGC_function_vcl_backend_error(VRT_CTX)
{
/* ... from ('Builtin' Line 160 Pos 23) */
{
{
VRT_count(ctx, 32);
END_;
VRT_SetHdr(ctx, &VGC_HDR_BERESP_Content_2d_Type,
"text/html; charset=utf-8",
vrt_magic_string_end
);
END_;
VRT_SetHdr(ctx, &VGC_HDR_BERESP_Retry_2d_After,
"5",
vrt_magic_string_end
);
END_;
VRT_l_beresp_body(ctx,
"<!DOCTYPE html>\n"
"<html>\n"
" <head>\n"
" <title>",
VRT_INT_string(ctx, VRT_r_beresp_status(ctx)),
" ",
VRT_r_beresp_reason(ctx),
"</title>\n"
" </head>\n"
" <body>\n"
" <h1>Error ",
VRT_INT_string(ctx, VRT_r_beresp_status(ctx)),
" ",
VRT_r_beresp_reason(ctx),
"</h1>\n"
" <p>",
VRT_r_beresp_reason(ctx),
"</p>\n"
" <h3>Guru Meditation:</h3>\n"
" <p>XID: ",
VRT_r_bereq_xid(ctx),
"</p>\n"
" <hr>\n"
" <p>Varnish cache server</p>\n"
" </body>\n"
"</html>\n"
"",
vrt_magic_string_end
);
END_;
VRT_handling(ctx, VCL_RET_DELIVER);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_backend_fetch(VRT_CTX)
{
/* ... from ('Builtin' Line 137 Pos 23) */
{
{
VRT_count(ctx, 25);
END_;
if (
(0 == VRT_strcmp(VRT_r_bereq_method(ctx), "GET"))
)
{
VRT_count(ctx, 26);
END_;
VRT_u_bereq_body(ctx);
END_;
}
VRT_count(ctx, 27);
END_;
VRT_handling(ctx, VCL_RET_FETCH);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_backend_response(VRT_CTX)
{
/* ... from ('/etc/varnish/default.vcl' Line 28 Pos 26) */
{
{
VRT_count(ctx, 2);
END_;
}
}
/* ... from ('Builtin' Line 144 Pos 26) */
{
{
VRT_count(ctx, 28);
END_;
if (
VRT_r_bereq_uncacheable(ctx)
)
{
VRT_count(ctx, 29);
END_;
VRT_handling(ctx, VCL_RET_DELIVER);
END_;
}
else if (
(
(VRT_r_beresp_ttl(ctx) <= (0) * 1)
||
(VRT_GetHdr(ctx, &VGC_HDR_BERESP_Set_2d_Cookie) != 0)
||
VRT_re_match(ctx, VRT_GetHdr(ctx, &VGC_HDR_BERESP_Surrogate_2d_control), VGC_re_2)
||
((
!((VRT_GetHdr(ctx, &VGC_HDR_BERESP_Surrogate_2d_control) != 0))
&&
VRT_re_match(ctx, VRT_GetHdr(ctx, &VGC_HDR_BERESP_Cache_2d_Control), VGC_re_3)
))
||
(0 == VRT_strcmp(VRT_GetHdr(ctx, &VGC_HDR_BERESP_Vary), "*"))
)
)
{
VRT_count(ctx, 30);
END_;
VRT_l_beresp_ttl(ctx,
(120) * 1
);
END_;
VRT_l_beresp_uncacheable(ctx,
(0==0)
);
END_;
}
VRT_count(ctx, 31);
END_;
VRT_handling(ctx, VCL_RET_DELIVER);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_deliver(VRT_CTX)
{
/* ... from ('/etc/varnish/default.vcl' Line 35 Pos 17) */
{
{
VRT_count(ctx, 3);
END_;
}
}
/* ... from ('Builtin' Line 106 Pos 17) */
{
{
VRT_count(ctx, 23);
END_;
VRT_handling(ctx, VCL_RET_DELIVER);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_fini(VRT_CTX)
{
/* ... from ('Builtin' Line 188 Pos 14) */
{
{
VRT_count(ctx, 34);
END_;
VRT_handling(ctx, VCL_RET_OK);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_hash(VRT_CTX)
{
/* ... from ('Builtin' Line 84 Pos 14) */
{
{
VRT_count(ctx, 17);
END_;
VRT_hashdata(ctx,
VRT_r_req_url(ctx),
vrt_magic_string_end
);
END_;
if (
(VRT_GetHdr(ctx, &VGC_HDR_REQ_host) != 0)
)
{
VRT_count(ctx, 18);
END_;
VRT_hashdata(ctx,
VRT_GetHdr(ctx, &VGC_HDR_REQ_host),
vrt_magic_string_end
);
END_;
}
else
{
VRT_count(ctx, 19);
END_;
VRT_hashdata(ctx,
VRT_IP_string(ctx, VRT_r_server_ip(ctx)),
vrt_magic_string_end
);
END_;
}
END_;
VRT_handling(ctx, VCL_RET_LOOKUP);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_hit(VRT_CTX)
{
/* ... from ('Builtin' Line 98 Pos 13) */
{
{
VRT_count(ctx, 21);
END_;
VRT_handling(ctx, VCL_RET_DELIVER);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_init(VRT_CTX)
{
/* ... from ('Builtin' Line 184 Pos 14) */
{
{
VRT_count(ctx, 33);
END_;
VRT_handling(ctx, VCL_RET_OK);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_miss(VRT_CTX)
{
/* ... from ('Builtin' Line 102 Pos 14) */
{
{
VRT_count(ctx, 22);
END_;
VRT_handling(ctx, VCL_RET_FETCH);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_pass(VRT_CTX)
{
/* ... from ('Builtin' Line 80 Pos 14) */
{
{
VRT_count(ctx, 16);
END_;
VRT_handling(ctx, VCL_RET_FETCH);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_pipe(VRT_CTX)
{
/* ... from ('Builtin' Line 71 Pos 14) */
{
{
VRT_count(ctx, 15);
END_;
VRT_handling(ctx, VCL_RET_PIPE);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_purge(VRT_CTX)
{
/* ... from ('Builtin' Line 94 Pos 15) */
{
{
VRT_count(ctx, 20);
END_;
VRT_synth(ctx,
200
,
"Purged"
);
VRT_handling(ctx, VCL_RET_SYNTH);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_recv(VRT_CTX)
{
/* ... from ('/etc/varnish/default.vcl' Line 21 Pos 14) */
{
{
VRT_count(ctx, 1);
END_;
}
}
/* ... from ('Builtin' Line 37 Pos 14) */
{
{
VRT_count(ctx, 4);
END_;
if (
(0 == VRT_strcmp(VRT_r_req_method(ctx), "PRI"))
)
{
VRT_count(ctx, 5);
END_;
VRT_synth(ctx,
405
,
(const char*)0
);
VRT_handling(ctx, VCL_RET_SYNTH);
END_;
}
VRT_count(ctx, 6);
END_;
if (
(
!((VRT_GetHdr(ctx, &VGC_HDR_REQ_host) != 0))
&&
(VRT_r_req_esi_level(ctx) == 0)
&&
VRT_re_match(ctx, VRT_r_req_proto(ctx), VGC_re_1)
)
)
{
VRT_count(ctx, 7);
END_;
VRT_synth(ctx,
400
,
(const char*)0
);
VRT_handling(ctx, VCL_RET_SYNTH);
END_;
}
VRT_count(ctx, 8);
END_;
if (
(
(0 != VRT_strcmp(VRT_r_req_method(ctx), "GET"))
&&
(0 != VRT_strcmp(VRT_r_req_method(ctx), "HEAD"))
&&
(0 != VRT_strcmp(VRT_r_req_method(ctx), "PUT"))
&&
(0 != VRT_strcmp(VRT_r_req_method(ctx), "POST"))
&&
(0 != VRT_strcmp(VRT_r_req_method(ctx), "TRACE"))
&&
(0 != VRT_strcmp(VRT_r_req_method(ctx), "OPTIONS"))
&&
(0 != VRT_strcmp(VRT_r_req_method(ctx), "DELETE"))
&&
(0 != VRT_strcmp(VRT_r_req_method(ctx), "PATCH"))
)
)
{
VRT_count(ctx, 9);
END_;
VRT_handling(ctx, VCL_RET_PIPE);
END_;
}
VRT_count(ctx, 10);
END_;
if (
(
(0 != VRT_strcmp(VRT_r_req_method(ctx), "GET"))
&&
(0 != VRT_strcmp(VRT_r_req_method(ctx), "HEAD"))
)
)
{
VRT_count(ctx, 11);
END_;
VRT_handling(ctx, VCL_RET_PASS);
END_;
}
VRT_count(ctx, 12);
END_;
if (
(
(VRT_GetHdr(ctx, &VGC_HDR_REQ_Authorization) != 0)
||
(VRT_GetHdr(ctx, &VGC_HDR_REQ_Cookie) != 0)
)
)
{
VRT_count(ctx, 13);
END_;
VRT_handling(ctx, VCL_RET_PASS);
END_;
}
VRT_count(ctx, 14);
END_;
VRT_handling(ctx, VCL_RET_HASH);
END_;
}
}
}
void v_matchproto_(vcl_func_f)
VGC_function_vcl_synth(VRT_CTX)
{
/* ... from ('Builtin' Line 113 Pos 15) */
{
{
VRT_count(ctx, 24);
END_;
VRT_SetHdr(ctx, &VGC_HDR_RESP_Content_2d_Type,
"text/html; charset=utf-8",
vrt_magic_string_end
);
END_;
VRT_SetHdr(ctx, &VGC_HDR_RESP_Retry_2d_After,
"5",
vrt_magic_string_end
);
END_;
VRT_l_resp_body(ctx,
"<!DOCTYPE html>\n"
"<html>\n"
" <head>\n"
" <title>",
VRT_INT_string(ctx, VRT_r_resp_status(ctx)),
" ",
VRT_r_resp_reason(ctx),
"</title>\n"
" </head>\n"
" <body>\n"
" <h1>Error ",
VRT_INT_string(ctx, VRT_r_resp_status(ctx)),
" ",
VRT_r_resp_reason(ctx),
"</h1>\n"
" <p>",
VRT_r_resp_reason(ctx),
"</p>\n"
" <h3>Guru Meditation:</h3>\n"
" <p>XID: ",
VRT_r_req_xid(ctx),
"</p>\n"
" <hr>\n"
" <p>Varnish cache server</p>\n"
" </body>\n"
"</html>\n"
"",
vrt_magic_string_end
);
END_;
VRT_handling(ctx, VCL_RET_DELIVER);
END_;
}
}
}
static int
VGC_Load(VRT_CTX)
{
vgc_inistep = 0;
size_t ndirector = 1UL;
/* 1 */
vsc_cluster = VRT_VSM_Cluster_New(ctx,
ndirector * VRT_backend_vsm_need(ctx));
if (vsc_cluster == 0)
return(1);
vgc_inistep = 1;
/* 2 */
vgc_backend_default =
VRT_new_backend_clustered(ctx, vsc_cluster,
&vgc_dir_priv_vgc_backend_default);
vgc_inistep = 2;
/* 3 */
VRT_re_init(&VGC_re_1, "^(\?i)HTTP/1.1");
vgc_inistep = 3;
/* 4 */
VRT_re_init(&VGC_re_2, "(\?i)no-store");
vgc_inistep = 4;
/* 5 */
VRT_re_init(&VGC_re_3, "(\?i:no-cache|no-store|private)");
vgc_inistep = 5;
/* 6 */
VGC_function_vcl_init(ctx);
vgc_inistep = 6;
if (*ctx->handling != VCL_RET_OK)
return(1);
return(0);
}
static int
VGC_Discard(VRT_CTX)
{
switch (vgc_inistep) {
case 6:
VGC_function_vcl_fini(ctx);
/* FALLTHROUGH */
case 5:
VRT_re_fini(VGC_re_3);
/* FALLTHROUGH */
case 4:
VRT_re_fini(VGC_re_2);
/* FALLTHROUGH */
case 3:
VRT_re_fini(VGC_re_1);
/* FALLTHROUGH */
case 2:
VRT_delete_backend(ctx, &vgc_backend_default);
/* FALLTHROUGH */
case 1:
VRT_VSM_Cluster_Destroy(ctx, &vsc_cluster);
/* FALLTHROUGH */
default:
break;
}
switch (vgc_inistep) {
case 6:
/* FALLTHROUGH */
case 5:
/* FALLTHROUGH */
case 4:
/* FALLTHROUGH */
case 3:
/* FALLTHROUGH */
case 2:
/* FALLTHROUGH */
case 1:
/* FALLTHROUGH */
default:
break;
}
return (0);
}
static int
VGC_Event(VRT_CTX, enum vcl_event_e ev)
{
if (ev == VCL_EVENT_LOAD)
return (VGC_Load(ctx));
if (ev == VCL_EVENT_DISCARD)
return (VGC_Discard(ctx));
(void)vgc_warmupstep;
return (0);
}
const struct VCL_conf VCL_conf = {
.magic = VCL_CONF_MAGIC,
.syntax = 40,
.event_vcl = VGC_Event,
.default_director = &vgc_backend_default,
.ref = VGC_ref,
.nref = VGC_NREFS,
.nsrc = VGC_NSRCS,
.srcname = srcname,
.srcbody = srcbody,
.nvmod = 0,
.backend_error_func = VGC_function_vcl_backend_error,
.backend_fetch_func = VGC_function_vcl_backend_fetch,
.backend_response_func = VGC_function_vcl_backend_response,
.deliver_func = VGC_function_vcl_deliver,
.fini_func = VGC_function_vcl_fini,
.hash_func = VGC_function_vcl_hash,
.hit_func = VGC_function_vcl_hit,
.init_func = VGC_function_vcl_init,
.miss_func = VGC_function_vcl_miss,
.pass_func = VGC_function_vcl_pass,
.pipe_func = VGC_function_vcl_pipe,
.purge_func = VGC_function_vcl_purge,
.recv_func = VGC_function_vcl_recv,
.synth_func = VGC_function_vcl_synth,
};
/*
* Symbol Table
*
* none VOID 41 41 acl
* none VOID 41 41 backend
* action VOID 40 41 ban
* var HTTP 0 99 bereq
* var BACKEND 0 99 bereq.backend
* var DURATION 0 99 bereq.between_bytes_timeout
* var BODY 0 99 bereq.body
* var DURATION 0 99 bereq.connect_timeout
* var DURATION 0 99 bereq.first_byte_timeout
* var BLOB 0 99 bereq.hash
* none HEADER 0 99 bereq.http*
* var BOOL 0 99 bereq.is_bgfetch
* var STRING 0 99 bereq.method
* var STRING 0 40 bereq.proto
* var STRING 41 99 bereq.proto
* var INT 0 99 bereq.retries
* var BOOL 0 99 bereq.uncacheable
* var STRING 0 99 bereq.url
* var STRING 0 99 bereq.xid
* var HTTP 0 99 beresp
* var DURATION 0 99 beresp.age
* var BACKEND 0 99 beresp.backend
* var IP 0 40 beresp.backend.ip
* var STRING 0 99 beresp.backend.name
* var BODY 0 99 beresp.body
* var BOOL 0 99 beresp.do_esi
* var BOOL 0 99 beresp.do_gunzip
* var BOOL 0 99 beresp.do_gzip
* var BOOL 0 99 beresp.do_stream
* var STRING 0 99 beresp.filters
* var DURATION 0 99 beresp.grace
* none HEADER 0 99 beresp.http*
* var HEADER 40 40 beresp.http.Cache-Control
* var HEADER 40 40 beresp.http.Content-Type
* var HEADER 40 40 beresp.http.Retry-After
* var HEADER 40 40 beresp.http.Set-Cookie
* var HEADER 40 40 beresp.http.Surrogate-control
* var HEADER 40 40 beresp.http.Vary
* var DURATION 0 99 beresp.keep
* var STRING 0 40 beresp.proto
* var STRING 41 99 beresp.proto
* var STRING 0 99 beresp.reason
* var INT 0 99 beresp.status
* var STEVEDORE 0 99 beresp.storage
* var STRING 0 40 beresp.storage_hint
* var DURATION 0 99 beresp.ttl
* var BOOL 0 99 beresp.uncacheable
* var BOOL 0 99 beresp.was_304
* action VOID 40 41 call
* none VOID 0 99 client
* var STRING 0 99 client.identity
* var IP 0 99 client.ip
* none VOID 41 41 default
* func BOOL 40 41 false
* action VOID 40 41 hash_data
* action VOID 40 41 if
* none VOID 41 41 import
* none VOID 0 99 local
* var STRING 41 99 local.endpoint
* var IP 0 99 local.ip
* var STRING 41 99 local.socket
* action VOID 40 41 new
* var TIME 0 99 now
* none VOID 0 99 obj
* var DURATION 0 99 obj.age
* var DURATION 0 99 obj.grace
* var INT 0 99 obj.hits
* none HEADER 0 99 obj.http*
* var DURATION 0 99 obj.keep
* var STRING 0 99 obj.proto
* var STRING 0 99 obj.reason
* var INT 0 99 obj.status
* var STEVEDORE 0 99 obj.storage
* var DURATION 0 99 obj.ttl
* var BOOL 0 99 obj.uncacheable
* none VOID 41 41 probe
* func STRING 40 41 regsub
* func STRING 40 41 regsuball
* none VOID 0 99 remote
* var IP 0 99 remote.ip
* var HTTP 0 99 req
* var BACKEND 0 99 req.backend_hint
* var BOOL 0 99 req.can_gzip
* var BOOL 0 40 req.esi
* var INT 0 99 req.esi_level
* var DURATION 0 99 req.grace
* var BLOB 0 99 req.hash
* var BOOL 0 99 req.hash_always_miss
* var BOOL 0 99 req.hash_ignore_busy
* none HEADER 0 99 req.http*
* var HEADER 40 40 req.http.Authorization
* var HEADER 40 40 req.http.Cookie
* var HEADER 40 40 req.http.host
* var BOOL 0 99 req.is_hitmiss
* var BOOL 0 99 req.is_hitpass
* var STRING 0 99 req.method
* var STRING 0 40 req.proto
* var STRING 41 99 req.proto
* var INT 0 99 req.restarts
* var STEVEDORE 0 99 req.storage
* var DURATION 0 99 req.ttl
* var STRING 0 99 req.url
* var STRING 0 99 req.xid
* none VOID 0 99 req_top
* none HEADER 0 99 req_top.http*
* var STRING 0 99 req_top.method
* var STRING 0 99 req_top.proto
* var STRING 0 99 req_top.url
* var HTTP 0 99 resp
* var BODY 0 99 resp.body
* var BOOL 41 99 resp.do_esi
* var STRING 0 99 resp.filters
* none HEADER 0 99 resp.http*
* var HEADER 40 40 resp.http.Content-Type
* var HEADER 40 40 resp.http.Retry-After
* var BOOL 0 99 resp.is_streaming
* var STRING 0 40 resp.proto
* var STRING 41 99 resp.proto
* var STRING 0 99 resp.reason
* var INT 0 99 resp.status
* action VOID 40 41 return
* none VOID 0 99 server
* var STRING 0 99 server.hostname
* var STRING 0 99 server.identity
* var IP 0 99 server.ip
* none VOID 41 99 sess
* var STRING 41 99 sess.xid
* action VOID 40 41 set
* none VOID 40 41 storage
* var STEVEDORE 40 41 storage.s0
* var BYTES 40 41 storage.s0.free_space
* var BOOL 40 41 storage.s0.happy
* var BYTES 40 41 storage.s0.used_space
* var STEVEDORE 40 41 storage.Transient
* var BYTES 40 41 storage.Transient.free_space
* var BOOL 40 41 storage.Transient.happy
* var BYTES 40 41 storage.Transient.used_space
* none VOID 41 41 sub
* action VOID 40 41 synthetic
* func BOOL 40 41 true
* action VOID 40 41 unset
* none VOID 41 41 vcl
* sub VOID 40 41 vcl_backend_error
* sub VOID 40 41 vcl_backend_fetch
* sub VOID 40 41 vcl_backend_response
* sub VOID 40 41 vcl_deliver
* sub VOID 40 41 vcl_fini
* sub VOID 40 41 vcl_hash
* sub VOID 40 41 vcl_hit
* sub VOID 40 41 vcl_init
* sub VOID 40 41 vcl_miss
* sub VOID 40 41 vcl_pass
* sub VOID 40 41 vcl_pipe
* sub VOID 40 41 vcl_purge
* sub VOID 40 41 vcl_recv
* sub VOID 40 41 vcl_synth
*/
However if I make a error in my VCL file, like replace .host with host, I get a VCC compiler error:
Message from VCC-compiler:
Expected '.' got 'host'
(program line 93), at
('/etc/varnish/default.vcl' Line 17 Pos 5)
host = "127.0.0.1";
----####---------------
In backend specification starting at:
('/etc/varnish/default.vcl' Line 16 Pos 1)
backend default {
#######----------
Running VCC-compiler failed, exited with 2
VCL compilation failed
Any ideas what am I doing wrong?
You're not doing anything wrong.
This is what the -C option does according to the docs:
Output VCL code compiled to C language
What you're seeing is the C representation of the VCL file. The VCC thread of the varnishd process will transpile the VLC code into C code. This C code will be compiled into machine code and the .so file that results from the compilation will be linked to the varnishd runtime process prior to execution.
As long as you're not making any syntax errors, the -C option will spit out the C code. Once you make a mistake in the VCL, the compilation will fail and you'll get an error.
VCL validation with varnishadm
There are other ways to validate your VCL file.
You can either add your VCL code as an inline string to varnishadm vcl.inline. See https://varnish-cache.org/docs/6.0/reference/varnish-cli.html#vcl-inline-configname-quoted-vclstring-auto-cold-warm for documentation.
You can also use the following commands to load, validate & discard the VCL file:
sudo varnishadm vcl.load validation default.vcl
sudo varnishadm vcl.discard validation
The first command will load the default.vcl file and try to compile it. When it success the validation configuration is stored and can be used in production through varnishadm vcl.use validation.
But we're not going to do that. Because this is only a validation run, we'll remove the validation config through varnishadm vcl.discard validation as seen in the example above.

Separate delimited string values in array into boolean variables

I have a dataset that lists different activities done in each day in a string array, similar concept asked here. Each activity is delimited and can easily be separated into columns, as I've had no problem doing in Excel.
activites
Work | family | date | gaming | relax | good sleep | shopping
Work | family | date | Nature | Crusin | reading | gaming | relax | good sleep | cooking | laundry
family | date | movies & tv | gaming | sport | relax | medium sleep | cooking
Work | family | date | Photography | gaming | relax | good sleep | medium sleep | cooking
Work | family | date | Nature | reading | gaming | relax | good sleep | cleaning
What I am trying to do is make each activity into a boolean variable which has its own column as such, so it indicates 0 for not having done the activity on that day and 1 for having done the activity. It would look something like this:
Work Family Date Gaming Relax
1 1 0 1 0
1 1 1 0 0
0 0 1 0 1
So, what I ended up doing was using my knowledge of Java to reformat data. I first separated the activities into their own variables, each containing a numerical (binary) value to indicate whether or not that activity had been done that day. I had to treat sleep quality separately, so that part looks a little wonky. Here's the code, which produced the correct output:
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(new FileReader("activities.txt"));
String[] actList = { "Work", "school", "family", "friends", "date", "nature", "crusin", "photography",
"making music/piano", "movies & tv", "reading", "gaming", "sport", "relax", "sleep", "shopping", "cleaning",
"cooking", "laundry" };
int row = 0;
while (scan.hasNextLine()) {
row++;
int col = 0;
int activityNo = 0;
int[] actValue = new int[actList.length];
String pipeDelim = scan.nextLine();
String[] actName = pipeDelim.split(" \\| ");
int sleepTagsUsed = 0;
while (activityNo < actName.length) {
col = 0;
for (String a : actName) {
if (a.contains("sleep")) {
col = 14;
if (a.equalsIgnoreCase("bad sleep") || a.equalsIgnoreCase("bad sleep\t")) {
if (col < actList.length) {
actValue[col] = 0;
if (sleepTagsUsed == 0) {
col++;
}
sleepTagsUsed++;
} else {
break;
}
if (!(activityNo > actName.length)) {
activityNo++;
}
} else if (a.equalsIgnoreCase("medium sleep") || a.equalsIgnoreCase("medium sleep\t")) {
if (col < actList.length) {
actValue[col] = 1;
if (sleepTagsUsed == 0) {
col++;
}
sleepTagsUsed++;
} else {
break;
}
if (!(activityNo > actName.length)) {
activityNo++;
}
} else if (a.equalsIgnoreCase("good sleep") || a.equalsIgnoreCase("good sleep\t")) {
if (col < actList.length) {
actValue[col] = 2;
if (sleepTagsUsed == 0) {
col++;
}
sleepTagsUsed++;
} else {
break;
}
if (!(activityNo > actName.length)) {
activityNo++;
}
} else if (a.equalsIgnoreCase("sleep early") || a.equalsIgnoreCase("sleep early\t")) {
if (col < actList.length) {
actValue[col] = 3;
if (sleepTagsUsed == 0) {
col++;
}
sleepTagsUsed++;
} else {
break;
}
if (!(activityNo > actName.length)) {
activityNo++;
}
} else {
if (col < actList.length) {
actValue[col] = -1;
} else {
break;
}
System.out.println("No sleep logged error");
}
} else {
int j = 0;
for (String i : actList) {
if (a.equalsIgnoreCase(i) || a.equalsIgnoreCase(i + "\t")) {
actValue[col] = 1;
if (activityNo > actName.length) {
break;
} else {
activityNo++;
break;
}
} else {
if (col < actList.length) {
j++;
if (j > col) {
actValue[col] = 0;
col++;
}
} else {
break;
}
}
}
col++;
}
}
}
for (int p : actValue) {
System.out.print(p + "\t");
}
System.out.println();
}
scan.close();
}

GoLang. I want to check the string for its contents for a criteria. How to do it in GoLang efficiently in terms of speed?

The string will only contain 0's or 4's. The string will start with 4. example: 444, 44, 40, 4400, 4440, etc. These all are valid strings but 404 is not valid.
Currently, I am checking if 4 is present immediately after 0. I am not sure that this one is efficient one.
If you mean leading 4 and following 0.
use regexp
package main
import (
"regexp"
)
func check(s string) bool {
return regexp.MustCompile(`^4+0*$`).MatchString(s)
}
func main() {
for _, tt := range []string{"444", "44", "40", "4400", "4440"} {
if !check(tt) {
panic("want true: " + tt)
}
}
for _, tt := range []string{"404", "040"} {
if check(tt) {
panic("want false: " + tt)
}
}
}
non-regexp
package main
func check(s string) bool {
i := 0
r := []rune(s)
for i = 0; i < len(r); i++ {
if r[i] != '4' {
break
}
}
if i == 0 {
return false
}
for ; i < len(r); i++ {
if r[i] != '0' {
return false
}
}
return true
}
func main() {
for _, tt := range []string{"444", "44", "40", "4400", "4440"} {
if !check(tt) {
panic("want true: " + tt)
}
}
for _, tt := range []string{"404", "040"} {
if check(tt) {
panic("want false: " + tt)
}
}
}
faster version
func check(s string) bool {
i, l := 0, len(s)
for ; i < l; i++ {
if s[i] != '4' {
break
}
}
if i == 0 {
return false
}
for ; i < l; i++ {
if s[i] != '0' {
return false
}
}
return true
}
For example,
package main
import "fmt"
func isFourZero(s string) bool {
i := 0
var four bool
for ; i < len(s) && s[i] == '4'; i++ {
four = true
}
if four {
if i >= len(s) {
return true
}
var zero bool
for ; i < len(s) && s[i] == '0'; i++ {
zero = true
}
if zero {
if i >= len(s) {
return true
}
}
}
return false
}
func main() {
tests := []struct{ s string }{
{"444"}, {"44"}, {"40"}, {"4400"}, {"4440"}, {"404"}, {"004"},
}
for _, test := range tests {
fmt.Printf("%q \t %t\n", test.s, isFourZero(test.s))
}
}
Output:
"444" true
"44" true
"40" true
"4400" true
"4440" true
"404" false
"004" false
Since we care about speed, let's look at some benchmarks:
BenchmarkIsFourZeroPeterSO-4 10000000 201 ns/op
BenchmarkValidateYogeshDesai-4 5000000 347 ns/op
BenchmarkCheckMattn-4 2000000 602 ns/op
fourzero_test.go:
package main
import (
"strings"
"testing"
)
var tests = []struct{ s string }{
{"444"}, {"44"}, {"40"}, {"4400"}, {"4440"}, {"404"}, {"004"},
}
func BenchmarkIsFourZeroPeterSO(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, test := range tests {
isFourZero(test.s)
}
}
}
func BenchmarkValidateYogeshDesai(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, test := range tests {
validate(test.s)
}
}
}
func BenchmarkCheckMattn(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, test := range tests {
check(test.s)
}
}
}
func isFourZero(s string) bool {
i := 0
var four bool
for ; i < len(s) && s[i] == '4'; i++ {
four = true
}
if four {
if i >= len(s) {
return true
}
var zero bool
for ; i < len(s) && s[i] == '0'; i++ {
zero = true
}
if zero {
if i >= len(s) {
return true
}
}
}
return false
}
func validate(str string) bool {
if strings.HasPrefix(str, "4") {
for i := 0; i < len(str)-1; i++ {
if (str[i] == '0') && (str[i+1] == '4') {
return false
}
}
} else {
return false
}
return true
}
func check(s string) bool {
i := 0
r := []rune(s)
for i = 0; i < len(r); i++ {
if r[i] != '4' {
break
}
}
if i == 0 {
return false
}
for ; i < len(r); i++ {
if r[i] != '0' {
return false
}
}
return true
}
No RegExp
package main
import (
"fmt"
"strings"
)
func validate(str string) bool {
if strings.HasPrefix(str, "4") {
for i:= 0; i < len(str)-1; i++ {
if (str[i] == '0') && (str[i+1] == '4') {
return false
}
}
}else { return false }
return true
}
func main() {
data := []string{"4", "44", "4400", "4440", "404", "004"}
for _, val := range data {
fmt.Println(validate(val))
}
}
Output:
true
true
true
false
false
The following is another implementation using only a single loop:
func yetAnotherValidation(s string) bool {
//INVALID: if empty OR not started with '4'
if len(s) == 0 || s[0] != '4' {
return false
}
//INVALID: if len(s) > 2 AND contains "404"
for k := 2; k < len(s); k++ {
if s[k] == '4' && s[k-1] == '0' && s[k-2] == '4' {
return false
}
}
return true
}
Note:
*404* (e.g. 404, 4404, 4040, ...) is INVALID.
If s contains a character other than 0 or 4, the result will be undefined (depending on the position of that character). If you need to ensure whether the input only contains 0 or 4, then:
func yetAnotherValidation2(s string) bool {
//INVALID: if empty OR not started with '4'
if len(s) == 0 || s[0] != '4' {
return false
}
//INVALID: if second digit is not 0 or 4
if len(s) > 1 && s[1] != '0' && s[1] != '4' {
return false
}
//For len(s) > 2
for k := 2; k < len(s); k++ {
if s[k] == '4' && s[k-1] == '0' && s[k-2] == '4' {
return false
} else if s[k] != '0' && s[k] != '4' {
//Neither 0 nor 4
return false
}
}
return true
}
UPDATE:
Test and benchmark result:
=== RUN TestValidate
444 true
44 true
40 true
4400 true
4440 true
404 false
004 false
--- PASS: TestValidate (0.00s)
BenchmarkYetAnotherValidation-4 50000000 38.5 ns/op
BenchmarkYetAnotherValidation2-4 30000000 45.6 ns/op
BenchmarkIsFourZero-4 20000000 54.5 ns/op
BenchmarkCheckMattn-4 10000000 144 ns/op
BenchmarkCheckMattnFast-4 30000000 50.2 ns/op

Tic-Tac-Toe - Iterative implementation of alpha beta tree search

Having issues trying to decipher the principal variation (PV) results.
"The principal variation is a path from the root to a leaf node, in which every node has the same value. This leaf node, whose value determines the minimax value of the root, is called the principal leaf."
The game demo below PV (move,eval) shows this line:
4,0 7,0 6,0 5,0 2,1
How can this be a valid PV since not ALL eval nodes have the same value? The AI never loses, but since the dizzying PV seems bogus, it casts a dark shadow on the AI logic. :( Hopefully, it's just a PV bug!
| | 0 | 1 | 2
---|---|--- ---|---|---
| | 3 | 4 | 5
---|---|--- ---|---|---
| | 6 | 7 | 8
Your move: 8
Thinking Cycles....: 2784300
Boards Generated...: 3956
Principal Variation: 4,0 7,0 6,0 5,0 2,1
Alpha-Beta Cutoffs.: 931
Computer Evaluation: 0
Computer Move......: 4
| | 0 | 1 | 2
---|---|--- ---|---|---
| X | 3 | 4 | 5
---|---|--- ---|---|---
| | O 6 | 7 | 8
Your move: 7
Thinking Cycles....: 410484
Boards Generated...: 575
Principal Variation: 6,0 5,0 2,1
Alpha-Beta Cutoffs.: 63
Computer Evaluation: 0
Computer Move......: 6
| | 0 | 1 | 2
---|---|--- ---|---|---
| X | 3 | 4 | 5
---|---|--- ---|---|---
X | O | O 6 | 7 | 8
Your move: 2
Thinking Cycles....: 42808
Boards Generated...: 45
Principal Variation: 5,0 3,0 1,0 0,0
Alpha-Beta Cutoffs.: 1
Computer Evaluation: 0
Computer Move......: 5
| | O 0 | 1 | 2
---|---|--- ---|---|---
| X | X 3 | 4 | 5
---|---|--- ---|---|---
X | O | O 6 | 7 | 8
Your move: 3
Thinking Cycles....: 6892
Boards Generated...: 4
Principal Variation: 0,0 1,0
Alpha-Beta Cutoffs.: 0
Computer Evaluation: 0
Computer Move......: 0
X | | O 0 | 1 | 2
---|---|--- ---|---|---
O | X | X 3 | 4 | 5
---|---|--- ---|---|---
X | O | O 6 | 7 | 8
Your move: 1
X | O | O 0 | 1 | 2
---|---|--- ---|---|---
O | X | X 3 | 4 | 5
---|---|--- ---|---|---
X | O | O 6 | 7 | 8
A draw! (*_*)
If anyone sees a bug in my code, please let me know. Thanks.
// Tic-Tac-Toe - Iterative implementation of alpha beta tree search.
// Built with Microsoft Visual Studio Professional 2013.
#include "stdafx.h"
#include <windows.h>
#include <intrin.h>
#include <stdint.h>
#define INFINITY 9999
#define NO_MOVE 9
#define NO_EVAL 2
#define X 1
#define O -1
#define Empty 0
struct values
{
int nodeMove;
int nodeEval;
int alpha;
int beta;
int player;
int board[9];
};
struct line
{
int nodeMove;
int nodeEval;
};
struct values moves[9];
int bestMove, bestEval;
int nodesCreated;
int abCutoffs;
int pvDepth, pvBestDepth;
// The principal variation pv[9] is a path from the root to a leaf node, in which every node
// has the same value. This leaf node, whose value determines the minimax value of the root,
// is called the principal leaf.
struct line pv[9] = {
{ NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL },
{ NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL },
{ NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL }
};
struct line bestPV[9] = {
{ NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL },
{ NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL },
{ NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL }, { NO_MOVE, NO_EVAL }
};
int board_eval(int *b)
{
// Rows.
if (b[0] && b[0] == b[1] && b[1] == b[2]) return b[0];
if (b[3] && b[3] == b[4] && b[4] == b[5]) return b[3];
if (b[6] && b[6] == b[7] && b[7] == b[8]) return b[6];
// Cols.
if (b[0] && b[0] == b[3] && b[3] == b[6]) return b[0];
if (b[1] && b[1] == b[4] && b[4] == b[7]) return b[1];
if (b[2] && b[2] == b[5] && b[5] == b[8]) return b[2];
// Center is empty.
if (!b[4]) return 0;
// Diags.
if (b[0] == b[4] && b[4] == b[8]) return b[0];
if (b[2] == b[4] && b[4] == b[6]) return b[2];
return 0;
}
void displayboard(int depth)
{
const char *t = "O X";
printf("\n\t %c | %c | %c\t\t 0 | 1 | 2\n", t[moves[depth].board[0] + 1], t[moves[depth].board[1] + 1], t[moves[depth].board[2] + 1]);
printf("\t---|---|---\t\t---|---|---\n");
printf("\t %c | %c | %c\t\t 3 | 4 | 5\n", t[moves[depth].board[3] + 1], t[moves[depth].board[4] + 1], t[moves[depth].board[5] + 1]);
printf("\t---|---|---\t\t---|---|---\n");
printf("\t %c | %c | %c\t\t 6 | 7 | 8\n\n", t[moves[depth].board[6] + 1], t[moves[depth].board[7] + 1], t[moves[depth].board[8] + 1]);
}
int find_move(int *board_arr, int nodeMove)
{
int i;
// Speedup loop using nodeMove instead of 0.
for (i = nodeMove; i < 9; i++) {
if (board_arr[i] == Empty)
return i;
}
return NO_MOVE;
}
int move_up_tree(int depth)
{
depth--;
if (depth == 0 && (moves[depth + 1].nodeEval > moves[depth].nodeEval))
{
bestMove = moves[depth].nodeMove;
bestEval = moves[depth + 1].nodeEval;
pvBestDepth = pvDepth;
pv[depth] = { bestMove, bestEval };
for (int i = 0; i < pvDepth; ++i)
{
bestPV[i].nodeMove = pv[i].nodeMove;
bestPV[i].nodeEval = pv[i].nodeEval;
pv[i] = { NO_MOVE, NO_EVAL };
}
}
if (moves[depth].player == X)
{
moves[depth].nodeEval = max(moves[depth].nodeEval, moves[depth + 1].nodeEval);
moves[depth].alpha = max(moves[depth].alpha, moves[depth].nodeEval);
}
else
{
moves[depth].nodeEval = min(moves[depth].nodeEval, moves[depth + 1].nodeEval);
moves[depth].beta = min(moves[depth].beta, moves[depth].nodeEval);
}
pv[depth] = { moves[depth].nodeMove, moves[depth].nodeEval };
moves[depth].nodeMove++;
moves[depth].nodeMove = find_move(moves[depth].board, moves[depth].nodeMove);
return depth;
}
int move_down_tree(int depth)
{
int eval;
depth++;
moves[depth] = moves[depth - 1];
nodesCreated++;
if (moves[depth].player == X)
{
moves[depth].board[moves[depth].nodeMove] = X;
moves[depth].player = O;
moves[depth].nodeEval = INFINITY;
}
else
{
moves[depth].board[moves[depth].nodeMove] = O;
moves[depth].player = X;
moves[depth].nodeEval = -INFINITY;
}
eval = board_eval(moves[depth].board);
// Leaf node.
if (eval || find_move(moves[depth].board, 0) == NO_MOVE)
{
moves[depth].nodeEval = eval;
moves[depth].nodeMove = NO_MOVE;
pvDepth = depth;
}
else
{
moves[depth].nodeMove = find_move(moves[depth].board, 0);
}
return depth;
}
void computer_move()
{
int depth = 0;
uint64_t c1, c2;
nodesCreated = 0;
abCutoffs = 0;
bestMove = NO_MOVE;
bestEval = -INFINITY;
moves[0].nodeMove = find_move(moves[0].board, 0);
moves[0].nodeEval = -INFINITY;
moves[0].alpha = -INFINITY;
moves[0].beta = INFINITY;
moves[0].player = X;
if (moves[0].nodeMove != NO_MOVE)
{
c1 = __rdtsc();
while (TRUE)
{
if (moves[depth].nodeMove == NO_MOVE)
{
if (depth == 0) break;
depth = move_up_tree(depth);
}
else if (moves[depth].alpha >= moves[depth].beta)
{
abCutoffs++;
moves[depth].nodeMove = NO_MOVE;
}
else
{
depth = move_down_tree(depth);
}
}
c2 = __rdtsc();
moves[0].board[bestMove] = X;
printf("\n");
printf("Thinking Cycles....: %d\n", c2 - c1);
printf("Boards Generated...: %d\n", nodesCreated);
printf("Principal Variation: ");
for (int i = 0; i < pvBestDepth; ++i) printf("%d,%d ", bestPV[i].nodeMove,bestPV[i].nodeEval);
printf("\n");
printf("Alpha-Beta Cutoffs.: %d\n", abCutoffs);
printf("Computer Evaluation: %d\n", bestEval);
printf("Computer Move......: %d\n", bestMove);
}
}
void init_board()
{
moves[0].board[0] = Empty;
moves[0].board[1] = Empty;
moves[0].board[2] = Empty;
moves[0].board[3] = Empty;
moves[0].board[4] = Empty;
moves[0].board[5] = Empty;
moves[0].board[6] = Empty;
moves[0].board[7] = Empty;
moves[0].board[8] = Empty;
}
void human_move()
{
int move;
char *p, s[100];
printf("Your move: ");
while (fgets(s, sizeof(s), stdin)) {
move = strtol(s, &p, 10);
if (p == s || *p != '\n') {
printf("Your move: ");
}
else break;
}
moves[0].board[move] = O;
}
int main(int argc, char **argv)
{
init_board();
displayboard(0);
while (1)
{
human_move();
computer_move();
displayboard(0);
if (board_eval(moves[0].board))
{
printf("Computer Wins! (-_-)\n");
init_board();
displayboard(0);
}
else if (find_move(moves[0].board, 0) == NO_MOVE)
{
printf("A draw! (*_*)\n");
init_board();
displayboard(0);
}
}
return 0;
}

Expando Metaclass behaviour dependant on whether a class is user defined or not?

While experimenting with ExpandMetaClass I ran into this behaviour:
class A {}
A.metaClass.foo = { 0 }
A.metaClass.foo = { 1 }
println (new A().foo())
A.metaClass.foo = { 2 }
println (new A().foo())
Collection.metaClass.foo = { 0 }
Collection.metaClass.foo = { 1 }
println ([].foo())
Collection.metaClass.foo = { 2 }
println ([].foo())
Which prints
1
2
1
1
Which doesn't seem to be consistent. What's the rationale behind this behavior?
Sounds like a bug. You should fill a JIRA.
It works per instance:
class A {}
A.metaClass.foo = { 0 }
A.metaClass.foo = { 1 }
assert (new A().foo()) == 1
A.metaClass.foo = { 2 }
assert (new A().foo()) == 2
Collection.metaClass.foo = { 0 }
Collection.metaClass.foo = { 1 }
assert ([].foo()) == 1
def j = []
j.getMetaClass().foo = { 2 }
assert (j.foo()) == 2

Resources