mojoshader_compiler.c
changeset 974 e4c4963e8889
parent 973 6d4cdbc21301
child 975 95b03c82cf51
equal deleted inserted replaced
973:6d4cdbc21301 974:e4c4963e8889
  3190 
  3190 
  3191     return ctx;
  3191     return ctx;
  3192 } // build_context
  3192 } // build_context
  3193 
  3193 
  3194 
  3194 
  3195 // parse the source code into an AST.
  3195 // This macro salsa is kinda nasty, but it's the smallest, least error-prone
  3196 static void parse_source(Context *ctx, const char *filename,
  3196 //  way I can find to do this well in C.  :/
  3197                          const char *source, unsigned int sourcelen,
  3197 
  3198                          const MOJOSHADER_preprocessorDefine *defines,
  3198 #define ADD_INTRINSIC(fn, ret, params) do { \
  3199                          unsigned int define_count,
  3199     push_function(ctx, fn, \
  3200                          MOJOSHADER_includeOpen include_open,
  3200         build_function_datatype(ctx, ret, STATICARRAYLEN(params), params, 1), \
  3201                          MOJOSHADER_includeClose include_close)
  3201         0); \
  3202 {
  3202 } while (0)
  3203     TokenData data;
  3203 
  3204     unsigned int tokenlen;
  3204 #define ADD_INTRINSIC_VECTOR(typestr, code) do { \
  3205     Token tokenval;
  3205     const MOJOSHADER_astDataType *dt; \
  3206     const char *token;
  3206     dt = get_usertype(ctx, typestr "1"); code; \
  3207     int lemon_token;
  3207     dt = get_usertype(ctx, typestr "2"); code; \
  3208     const char *fname;
  3208     dt = get_usertype(ctx, typestr "3"); code; \
  3209     Preprocessor *pp;
  3209     dt = get_usertype(ctx, typestr "4"); code; \
  3210     void *parser;
  3210 } while (0)
  3211 
  3211 
  3212     if (!include_open) include_open = MOJOSHADER_internal_include_open;
  3212 #define ADD_INTRINSIC_VECTOR_FLOAT(code) ADD_INTRINSIC_VECTOR("float", code)
  3213     if (!include_close) include_close = MOJOSHADER_internal_include_close;
  3213 #define ADD_INTRINSIC_VECTOR_INT(code) ADD_INTRINSIC_VECTOR("int", code)
  3214 
  3214 #define ADD_INTRINSIC_VECTOR_BOOL(code) ADD_INTRINSIC_VECTOR("bool", code)
  3215     pp = preprocessor_start(filename, source, sourcelen, include_open,
  3215 
  3216                             include_close, defines, define_count, 0,
  3216 #define ADD_INTRINSIC_MATRIX(typestr, code) do { \
  3217                             MallocBridge, FreeBridge, ctx);
  3217     const MOJOSHADER_astDataType *dt; \
  3218     if (pp == NULL)
  3218     dt = get_usertype(ctx, typestr "1x1"); code; \
  3219     {
  3219     dt = get_usertype(ctx, typestr "1x2"); code; \
  3220         assert(ctx->out_of_memory);  // shouldn't fail for any other reason.
  3220     dt = get_usertype(ctx, typestr "1x3"); code; \
  3221         return;
  3221     dt = get_usertype(ctx, typestr "1x4"); code; \
  3222     } // if
  3222     dt = get_usertype(ctx, typestr "2x1"); code; \
  3223 
  3223     dt = get_usertype(ctx, typestr "2x2"); code; \
  3224     parser = ParseHLSLAlloc(ctx->malloc, ctx->malloc_data);
  3224     dt = get_usertype(ctx, typestr "2x3"); code; \
  3225     if (parser == NULL)
  3225     dt = get_usertype(ctx, typestr "2x4"); code; \
  3226     {
  3226     dt = get_usertype(ctx, typestr "3x1"); code; \
  3227         assert(ctx->out_of_memory);  // shouldn't fail for any other reason.
  3227     dt = get_usertype(ctx, typestr "3x2"); code; \
  3228         preprocessor_end(pp);
  3228     dt = get_usertype(ctx, typestr "3x3"); code; \
  3229         return;
  3229     dt = get_usertype(ctx, typestr "3x4"); code; \
  3230     } // if
  3230     dt = get_usertype(ctx, typestr "4x1"); code; \
  3231 
  3231     dt = get_usertype(ctx, typestr "4x2"); code; \
  3232     // !!! FIXME: check if (parser == NULL)...
  3232     dt = get_usertype(ctx, typestr "4x3"); code; \
  3233 
  3233     dt = get_usertype(ctx, typestr "4x4"); code; \
  3234     SymbolScope *start_scope = ctx->usertypes.scope;
  3234 } while (0)
  3235 
  3235 
  3236     #if DEBUG_COMPILER_PARSER
  3236 #define ADD_INTRINSIC_MATRIX_FLOAT(code) ADD_INTRINSIC_MATRIX("float", code)
  3237     ParseHLSLTrace(stdout, "COMPILER: ");
  3237 #define ADD_INTRINSIC_MATRIX_INT(code) ADD_INTRINSIC_MATRIX("int", code)
  3238     #endif
  3238 #define ADD_INTRINSIC_MATRIX_BOOL(code) ADD_INTRINSIC_MATRIX("bool", code)
  3239 
  3239 
  3240     // !!! FIXME: move this to a subroutine.
  3240 #define ADD_INTRINSIC_ANY(scalar, typestr, code) do { \
       
  3241     { const MOJOSHADER_astDataType *dt = scalar; code; } \
       
  3242     ADD_INTRINSIC_VECTOR(typestr, code); \
       
  3243     ADD_INTRINSIC_MATRIX(typestr, code); \
       
  3244 } while (0)
       
  3245 
       
  3246 #define ADD_INTRINSIC_ANY_FLOAT(code) do { \
       
  3247     ADD_INTRINSIC_ANY(&ctx->dt_double, "double", code); \
       
  3248     ADD_INTRINSIC_ANY(&ctx->dt_half, "half", code); \
       
  3249     ADD_INTRINSIC_ANY(&ctx->dt_float, "float", code); \
       
  3250 } while (0)
       
  3251 #define ADD_INTRINSIC_ANY_INT(code) do { \
       
  3252     ADD_INTRINSIC_ANY(&ctx->dt_uint, "uint", code); \
       
  3253     ADD_INTRINSIC_ANY(&ctx->dt_int, "int", code); \
       
  3254 } while (0)
       
  3255 
       
  3256 #define ADD_INTRINSIC_ANY_BOOL(code) ADD_INTRINSIC_ANY(&ctx->dt_bool, "bool", code)
       
  3257 
       
  3258 static void add_intrinsic1(Context *ctx, const char *fn,
       
  3259                            const MOJOSHADER_astDataType *ret,
       
  3260                            const MOJOSHADER_astDataType *dt1)
       
  3261 {
       
  3262     const MOJOSHADER_astDataType *params[] = { dt1 };
       
  3263     ADD_INTRINSIC(fn, ret, params);
       
  3264 } // add_intrinsic1
       
  3265 
       
  3266 static void add_intrinsic2(Context *ctx, const char *fn,
       
  3267                            const MOJOSHADER_astDataType *ret,
       
  3268                            const MOJOSHADER_astDataType *dt1,
       
  3269                            const MOJOSHADER_astDataType *dt2)
       
  3270 {
       
  3271     const MOJOSHADER_astDataType *params[] = { dt1, dt2 };
       
  3272     ADD_INTRINSIC(fn, ret, params);
       
  3273 } // add_intrinsic2
       
  3274 
       
  3275 static void add_intrinsic3(Context *ctx, const char *fn,
       
  3276                            const MOJOSHADER_astDataType *ret,
       
  3277                            const MOJOSHADER_astDataType *dt1,
       
  3278                            const MOJOSHADER_astDataType *dt2,
       
  3279                            const MOJOSHADER_astDataType *dt3)
       
  3280 {
       
  3281     const MOJOSHADER_astDataType *params[] = { dt1, dt2, dt3 };
       
  3282     ADD_INTRINSIC(fn, ret, params);
       
  3283 } // add_intrinsic3
       
  3284 
       
  3285 static void add_intrinsic4(Context *ctx, const char *fn,
       
  3286                            const MOJOSHADER_astDataType *ret,
       
  3287                            const MOJOSHADER_astDataType *dt1,
       
  3288                            const MOJOSHADER_astDataType *dt2,
       
  3289                            const MOJOSHADER_astDataType *dt3,
       
  3290                            const MOJOSHADER_astDataType *dt4)
       
  3291 {
       
  3292     const MOJOSHADER_astDataType *params[] = { dt1, dt2, dt3, dt4 };
       
  3293     ADD_INTRINSIC(fn, ret, params);
       
  3294 } // add_intrinsic4
       
  3295 
       
  3296 // PLEASE NOTE that add_intrinsic*() is called AFTER the various
       
  3297 //  ADD_INTRINSIC_* macros, even though these look like functions that
       
  3298 //  should be called first. They might be called multiple times by the macro.
       
  3299 //  The variable "dt" is defined by the macro for use by your code.
       
  3300 static void add_intrinsic_SAME1_ANYf(Context *ctx, const char *fn)
       
  3301 {
       
  3302     ADD_INTRINSIC_ANY_FLOAT(add_intrinsic1(ctx, fn, dt, dt));
       
  3303 } // add_intrinsic_SAME1_ANYf
       
  3304 
       
  3305 static void add_intrinsic_SAME1_ANYfi(Context *ctx, const char *fn)
       
  3306 {
       
  3307     ADD_INTRINSIC_ANY_INT(add_intrinsic1(ctx, fn, dt, dt));
       
  3308     add_intrinsic_SAME1_ANYf(ctx, fn);
       
  3309 } // add_intrinsic_SAME1_ANYfi
       
  3310 
       
  3311 static void add_intrinsic_BOOL_ANYf(Context *ctx, const char *fn)
       
  3312 {
       
  3313     ADD_INTRINSIC_ANY_FLOAT(add_intrinsic1(ctx, fn, &ctx->dt_bool, dt));
       
  3314 } // add_intrinsic_BOOL_ANYf
       
  3315 
       
  3316 static void add_intrinsic_BOOL_ANYfib(Context *ctx, const char *fn)
       
  3317 {
       
  3318     ADD_INTRINSIC_ANY_BOOL(add_intrinsic1(ctx, fn, &ctx->dt_bool, dt));
       
  3319     ADD_INTRINSIC_ANY_INT(add_intrinsic1(ctx, fn, &ctx->dt_bool, dt));
       
  3320     add_intrinsic_BOOL_ANYf(ctx, fn);
       
  3321 } // add_intrinsic_BOOL_ANYfib
       
  3322 
       
  3323 static void add_intrinsic_SAME1_ANYf_SAME1(Context *ctx, const char *fn)
       
  3324 {
       
  3325     ADD_INTRINSIC_ANY_FLOAT(add_intrinsic2(ctx, fn, dt, dt, dt));
       
  3326 } // add_intrinsic_SAME1_ANYf_SAME1
       
  3327 
       
  3328 static void add_intrinsic_SAME1_ANYfi_SAME1(Context *ctx, const char *fn)
       
  3329 {
       
  3330     ADD_INTRINSIC_ANY_INT(add_intrinsic2(ctx, fn, dt, dt, dt));
       
  3331     add_intrinsic_SAME1_ANYf_SAME1(ctx, fn);
       
  3332 } // add_intrinsic_SAME1_ANYfi_SAME1
       
  3333 
       
  3334 static void add_intrinsic_SAME1_ANYf_SAME1_SAME1(Context *ctx, const char *fn)
       
  3335 {
       
  3336     ADD_INTRINSIC_ANY_FLOAT(add_intrinsic3(ctx, fn, dt, dt, dt, dt));
       
  3337 } // add_intrinsic_SAME1_ANYf_SAME1_SAME1
       
  3338 
       
  3339 static void add_intrinsic_SAME1_ANYfi_SAME1_SAME1(Context *ctx, const char *fn)
       
  3340 {
       
  3341     ADD_INTRINSIC_ANY_INT(add_intrinsic3(ctx, fn, dt, dt, dt, dt));
       
  3342     add_intrinsic_SAME1_ANYf_SAME1_SAME1(ctx, fn);
       
  3343 } // add_intrinsic_SAME1_ANYfi_SAME1_SAME1
       
  3344 
       
  3345 static void add_intrinsic_SAME1_Mfib(Context *ctx, const char *fn)
       
  3346 {
       
  3347     ADD_INTRINSIC_MATRIX_BOOL(add_intrinsic1(ctx, fn, dt, dt));
       
  3348     ADD_INTRINSIC_MATRIX_INT(add_intrinsic1(ctx, fn, dt, dt));
       
  3349     ADD_INTRINSIC_MATRIX_FLOAT(add_intrinsic1(ctx, fn, dt, dt));
       
  3350 } // add_intrinsic_SAME1_Mfib
       
  3351 
       
  3352 static void add_intrinsic_SAME1_Vf(Context *ctx, const char *fn)
       
  3353 {
       
  3354     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic1(ctx, fn, dt, dt));
       
  3355 } // add_intrinsic_SAME1_Vf
       
  3356 
       
  3357 static void add_intrinsic_SAME1_Vf_SAME1_SAME1(Context *ctx, const char *fn)
       
  3358 {
       
  3359     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic3(ctx, fn, dt, dt, dt, dt));
       
  3360 } // add_intrinsic_SAME1_Vf_SAME1_SAME1
       
  3361 
       
  3362 static void add_intrinsic_SAME1_Vf_SAME1_f(Context *ctx, const char *fn)
       
  3363 {
       
  3364     const MOJOSHADER_astDataType *f = &ctx->dt_float;
       
  3365     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic3(ctx, fn, dt, dt, dt, f));
       
  3366 } // add_intrinsic_SAME1_Vf_SAME1_f
       
  3367 
       
  3368 static void add_intrinsic_VOID_ANYf(Context *ctx, const char *fn)
       
  3369 {
       
  3370     ADD_INTRINSIC_ANY_FLOAT(add_intrinsic1(ctx, fn, NULL, dt));
       
  3371 } // add_intrinsic_VOID_ANYf
       
  3372 
       
  3373 static void add_intrinsic_VOID_ANYf_SAME1_SAME1(Context *ctx, const char *fn)
       
  3374 {
       
  3375     ADD_INTRINSIC_ANY_FLOAT(add_intrinsic3(ctx, fn, NULL, dt, dt, dt));
       
  3376 } // add_intrinsic_VOID_ANYf_SAME1_SAME1
       
  3377 
       
  3378 static void add_intrinsic_f_SQUAREMATRIXf(Context *ctx, const char *fn)
       
  3379 {
       
  3380     add_intrinsic1(ctx, fn, &ctx->dt_float, get_usertype(ctx, "float1x1"));
       
  3381     add_intrinsic1(ctx, fn, &ctx->dt_float, get_usertype(ctx, "float2x2"));
       
  3382     add_intrinsic1(ctx, fn, &ctx->dt_float, get_usertype(ctx, "float3x3"));
       
  3383     add_intrinsic1(ctx, fn, &ctx->dt_float, get_usertype(ctx, "float4x4"));
       
  3384 } // add_intrinsic_f_SQUAREMATRIXf
       
  3385 
       
  3386 static void add_intrinsic_f_Vf(Context *ctx, const char *fn)
       
  3387 {
       
  3388     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic1(ctx, fn, &ctx->dt_float, dt));
       
  3389 } // add_intrinsic_f_Vf
       
  3390 
       
  3391 static void add_intrinsic_fi_Vfi_SAME1(Context *ctx, const char *fn)
       
  3392 {
       
  3393     ADD_INTRINSIC_VECTOR_INT(add_intrinsic2(ctx, fn, &ctx->dt_int, dt, dt));
       
  3394     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, &ctx->dt_float, dt, dt));
       
  3395 } // add_intrinsic_fi_Vfi_SAME1
       
  3396 
       
  3397 static void add_intrinsic_f_Vf_SAME1(Context *ctx, const char *fn)
       
  3398 {
       
  3399     const MOJOSHADER_astDataType *f = &ctx->dt_float;
       
  3400     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, f, dt, dt));
       
  3401 } // add_intrinsic_f_Vf_SAME1
       
  3402 
       
  3403 static void add_intrinsic_3f_3f_3f(Context *ctx, const char *fn)
       
  3404 {
       
  3405     const MOJOSHADER_astDataType *dt = get_usertype(ctx, "float3");
       
  3406     add_intrinsic2(ctx, fn, dt, dt, dt);
       
  3407 } // add_intrinsic_3f_3f_3f
       
  3408 
       
  3409 static void add_intrinsic_4f_f_f_f(Context *ctx, const char *fn)
       
  3410 {
       
  3411     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3412     const MOJOSHADER_astDataType *f = &ctx->dt_float;
       
  3413     add_intrinsic3(ctx, fn, f4, f, f, f);
       
  3414 } // add_intrinsic_4f_f_f_f
       
  3415 
       
  3416 static void add_intrinsic_4f_s1_4f(Context *ctx, const char *fn)
       
  3417 {
       
  3418     const MOJOSHADER_astDataType *dt = get_usertype(ctx, "float4");
       
  3419     add_intrinsic2(ctx, fn, dt, &ctx->dt_sampler1d, dt);
       
  3420 } // add_intrinsic_4f_s1_4f
       
  3421 
       
  3422 static void add_intrinsic_4f_s1_f(Context *ctx, const char *fn)
       
  3423 {
       
  3424     const MOJOSHADER_astDataType *dt = get_usertype(ctx, "float4");
       
  3425     add_intrinsic2(ctx, fn, dt, &ctx->dt_sampler1d, &ctx->dt_float);
       
  3426 } // add_intrinsic_4f_s1_f
       
  3427 
       
  3428 static void add_intrinsic_4f_s1_f_f_f(Context *ctx, const char *fn)
       
  3429 {
       
  3430     const MOJOSHADER_astDataType *dt = get_usertype(ctx, "float4");
       
  3431     const MOJOSHADER_astDataType *f = &ctx->dt_float;
       
  3432     add_intrinsic4(ctx, fn, dt, &ctx->dt_sampler1d, f, f, f);
       
  3433 } // add_intrinsic_4f_s1_f_f_f
       
  3434 
       
  3435 static void add_intrinsic_4f_s2_2f(Context *ctx, const char *fn)
       
  3436 {
       
  3437     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3438     const MOJOSHADER_astDataType *f2 = get_usertype(ctx, "float2");
       
  3439     add_intrinsic2(ctx, fn, f4, &ctx->dt_sampler2d, f2);
       
  3440 } // add_intrinsic_4f_s2_2f
       
  3441 
       
  3442 static void add_intrinsic_4f_s2_2f_2f_2f(Context *ctx, const char *fn)
       
  3443 {
       
  3444     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3445     const MOJOSHADER_astDataType *f2 = get_usertype(ctx, "float2");
       
  3446     add_intrinsic4(ctx, fn, f4, &ctx->dt_sampler2d, f2, f2, f2);
       
  3447 } // add_intrinsic_4f_s2_2f_2f_2f
       
  3448 
       
  3449 static void add_intrinsic_4f_s2_4f(Context *ctx, const char *fn)
       
  3450 {
       
  3451     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3452     add_intrinsic2(ctx, fn, f4, &ctx->dt_sampler2d, f4);
       
  3453 } // add_intrinsic_4f_s2_4f
       
  3454 
       
  3455 static void add_intrinsic_4f_s3_3f(Context *ctx, const char *fn)
       
  3456 {
       
  3457     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3458     const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
       
  3459     add_intrinsic2(ctx, fn, f4, &ctx->dt_sampler3d, f3);
       
  3460 } // add_intrinsic_4f_s3_3f
       
  3461 
       
  3462 static void add_intrinsic_4f_s3_3f_3f_3f(Context *ctx, const char *fn)
       
  3463 {
       
  3464     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3465     const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
       
  3466     add_intrinsic4(ctx, fn, f4, &ctx->dt_sampler3d, f3, f3, f3);
       
  3467 } // add_intrinsic_4f_s3_3f_3f_3f
       
  3468 
       
  3469 static void add_intrinsic_4f_s3_4f(Context *ctx, const char *fn)
       
  3470 {
       
  3471     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3472     add_intrinsic2(ctx, fn, f4, &ctx->dt_sampler3d, f4);
       
  3473 } // add_intrinsic_4f_s3_4f
       
  3474 
       
  3475 static void add_intrinsic_4f_sc_3f(Context *ctx, const char *fn)
       
  3476 {
       
  3477     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3478     const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
       
  3479     add_intrinsic2(ctx, fn, f4, &ctx->dt_samplercube, f3);
       
  3480 } // add_intrinsic_4f_sc_3f
       
  3481 
       
  3482 static void add_intrinsic_4f_sc_3f_3f_3f(Context *ctx, const char *fn)
       
  3483 {
       
  3484     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3485     const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
       
  3486     add_intrinsic4(ctx, fn, f4, &ctx->dt_samplercube, f3, f3, f3);
       
  3487 } // add_intrinsic_4f_sc_3f_3f_3f
       
  3488 
       
  3489 static void add_intrinsic_4f_sc_4f(Context *ctx, const char *fn)
       
  3490 {
       
  3491     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3492     add_intrinsic2(ctx, fn, f4, &ctx->dt_samplercube, f4);
       
  3493 } // add_intrinsic_4f_sc_4f
       
  3494 
       
  3495 static void add_intrinsic_4i_4f(Context *ctx, const char *fn)
       
  3496 {
       
  3497     const MOJOSHADER_astDataType *i4 = get_usertype(ctx, "int4");
       
  3498     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3499     add_intrinsic1(ctx, fn, i4, f4);
       
  3500 } // add_intrinsic_4i_4f
       
  3501 
       
  3502 static void add_intrinsic_mul(Context *ctx, const char *fn)
       
  3503 {
       
  3504     // mul() is nasty, since there's a bunch of overloads that aren't just
       
  3505     //  related to vector size.
       
  3506     // !!! FIXME: needs half, double, uint...
       
  3507     const MOJOSHADER_astDataType *dtf = &ctx->dt_float;
       
  3508     const MOJOSHADER_astDataType *dti = &ctx->dt_int;
       
  3509     const MOJOSHADER_astDataType *f1 = get_usertype(ctx, "float1");
       
  3510     const MOJOSHADER_astDataType *f2 = get_usertype(ctx, "float2");
       
  3511     const MOJOSHADER_astDataType *f3 = get_usertype(ctx, "float3");
       
  3512     const MOJOSHADER_astDataType *f4 = get_usertype(ctx, "float4");
       
  3513     const MOJOSHADER_astDataType *i1 = get_usertype(ctx, "int1");
       
  3514     const MOJOSHADER_astDataType *i2 = get_usertype(ctx, "int2");
       
  3515     const MOJOSHADER_astDataType *i3 = get_usertype(ctx, "int3");
       
  3516     const MOJOSHADER_astDataType *i4 = get_usertype(ctx, "int4");
       
  3517     const MOJOSHADER_astDataType *f1x1 = get_usertype(ctx, "float1x1");
       
  3518     const MOJOSHADER_astDataType *f1x2 = get_usertype(ctx, "float1x2");
       
  3519     const MOJOSHADER_astDataType *f1x3 = get_usertype(ctx, "float1x3");
       
  3520     const MOJOSHADER_astDataType *f1x4 = get_usertype(ctx, "float1x4");
       
  3521     const MOJOSHADER_astDataType *f2x1 = get_usertype(ctx, "float2x1");
       
  3522     const MOJOSHADER_astDataType *f2x2 = get_usertype(ctx, "float2x2");
       
  3523     const MOJOSHADER_astDataType *f2x3 = get_usertype(ctx, "float2x3");
       
  3524     const MOJOSHADER_astDataType *f2x4 = get_usertype(ctx, "float2x4");
       
  3525     const MOJOSHADER_astDataType *f3x1 = get_usertype(ctx, "float3x1");
       
  3526     const MOJOSHADER_astDataType *f3x2 = get_usertype(ctx, "float3x2");
       
  3527     const MOJOSHADER_astDataType *f3x3 = get_usertype(ctx, "float3x3");
       
  3528     const MOJOSHADER_astDataType *f3x4 = get_usertype(ctx, "float3x4");
       
  3529     const MOJOSHADER_astDataType *f4x1 = get_usertype(ctx, "float4x1");
       
  3530     const MOJOSHADER_astDataType *f4x2 = get_usertype(ctx, "float4x2");
       
  3531     const MOJOSHADER_astDataType *f4x3 = get_usertype(ctx, "float4x3");
       
  3532     const MOJOSHADER_astDataType *f4x4 = get_usertype(ctx, "float4x4");
       
  3533     const MOJOSHADER_astDataType *i1x1 = get_usertype(ctx, "int1x1");
       
  3534     const MOJOSHADER_astDataType *i1x2 = get_usertype(ctx, "int1x2");
       
  3535     const MOJOSHADER_astDataType *i1x3 = get_usertype(ctx, "int1x3");
       
  3536     const MOJOSHADER_astDataType *i1x4 = get_usertype(ctx, "int1x4");
       
  3537     const MOJOSHADER_astDataType *i2x1 = get_usertype(ctx, "int2x1");
       
  3538     const MOJOSHADER_astDataType *i2x2 = get_usertype(ctx, "int2x2");
       
  3539     const MOJOSHADER_astDataType *i2x3 = get_usertype(ctx, "int2x3");
       
  3540     const MOJOSHADER_astDataType *i2x4 = get_usertype(ctx, "int2x4");
       
  3541     const MOJOSHADER_astDataType *i3x1 = get_usertype(ctx, "int3x1");
       
  3542     const MOJOSHADER_astDataType *i3x2 = get_usertype(ctx, "int3x2");
       
  3543     const MOJOSHADER_astDataType *i3x3 = get_usertype(ctx, "int3x3");
       
  3544     const MOJOSHADER_astDataType *i3x4 = get_usertype(ctx, "int3x4");
       
  3545     const MOJOSHADER_astDataType *i4x1 = get_usertype(ctx, "int4x1");
       
  3546     const MOJOSHADER_astDataType *i4x2 = get_usertype(ctx, "int4x2");
       
  3547     const MOJOSHADER_astDataType *i4x3 = get_usertype(ctx, "int4x3");
       
  3548     const MOJOSHADER_astDataType *i4x4 = get_usertype(ctx, "int4x4");
       
  3549 
       
  3550     // scalar * scalar
       
  3551     add_intrinsic2(ctx, fn, dti, dti, dti);
       
  3552     add_intrinsic2(ctx, fn, dtf, dtf, dtf);
       
  3553 
       
  3554     // scalar * vector
       
  3555     ADD_INTRINSIC_VECTOR_INT(add_intrinsic2(ctx, fn, dt, dti, dt));
       
  3556     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, dt, dtf, dt));
       
  3557 
       
  3558     // scalar * matrix
       
  3559     ADD_INTRINSIC_MATRIX_INT(add_intrinsic2(ctx, fn, dt, dti, dt));
       
  3560     ADD_INTRINSIC_MATRIX_FLOAT(add_intrinsic2(ctx, fn, dt, dtf, dt));
       
  3561 
       
  3562     // vector * scalar
       
  3563     ADD_INTRINSIC_VECTOR_INT(add_intrinsic2(ctx, fn, dt, dt, dti));
       
  3564     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, dt, dt, dtf));
       
  3565 
       
  3566     // vector * vector
       
  3567     ADD_INTRINSIC_VECTOR_INT(add_intrinsic2(ctx, fn, dti, dt, dt));
       
  3568     ADD_INTRINSIC_VECTOR_FLOAT(add_intrinsic2(ctx, fn, dtf, dt, dt));
       
  3569 
       
  3570     // vector * matrix
       
  3571     add_intrinsic2(ctx, fn, i1, i1, i1x1);
       
  3572     add_intrinsic2(ctx, fn, i2, i1, i1x2);
       
  3573     add_intrinsic2(ctx, fn, i3, i1, i1x3);
       
  3574     add_intrinsic2(ctx, fn, i4, i1, i1x4);
       
  3575     add_intrinsic2(ctx, fn, i1, i2, i2x1);
       
  3576     add_intrinsic2(ctx, fn, i2, i2, i2x2);
       
  3577     add_intrinsic2(ctx, fn, i3, i2, i2x3);
       
  3578     add_intrinsic2(ctx, fn, i4, i2, i2x4);
       
  3579     add_intrinsic2(ctx, fn, i1, i3, i3x1);
       
  3580     add_intrinsic2(ctx, fn, i2, i3, i3x2);
       
  3581     add_intrinsic2(ctx, fn, i3, i3, i3x3);
       
  3582     add_intrinsic2(ctx, fn, i4, i3, i3x4);
       
  3583     add_intrinsic2(ctx, fn, i1, i4, i4x1);
       
  3584     add_intrinsic2(ctx, fn, i2, i4, i4x2);
       
  3585     add_intrinsic2(ctx, fn, i3, i4, i4x3);
       
  3586     add_intrinsic2(ctx, fn, i4, i4, i4x4);
       
  3587     add_intrinsic2(ctx, fn, f1, f1, f1x1);
       
  3588     add_intrinsic2(ctx, fn, f2, f1, f1x2);
       
  3589     add_intrinsic2(ctx, fn, f3, f1, f1x3);
       
  3590     add_intrinsic2(ctx, fn, f4, f1, f1x4);
       
  3591     add_intrinsic2(ctx, fn, f1, f2, f2x1);
       
  3592     add_intrinsic2(ctx, fn, f2, f2, f2x2);
       
  3593     add_intrinsic2(ctx, fn, f3, f2, f2x3);
       
  3594     add_intrinsic2(ctx, fn, f4, f2, f2x4);
       
  3595     add_intrinsic2(ctx, fn, f1, f3, f3x1);
       
  3596     add_intrinsic2(ctx, fn, f2, f3, f3x2);
       
  3597     add_intrinsic2(ctx, fn, f3, f3, f3x3);
       
  3598     add_intrinsic2(ctx, fn, f4, f3, f3x4);
       
  3599     add_intrinsic2(ctx, fn, f1, f4, f4x1);
       
  3600     add_intrinsic2(ctx, fn, f2, f4, f4x2);
       
  3601     add_intrinsic2(ctx, fn, f3, f4, f4x3);
       
  3602     add_intrinsic2(ctx, fn, f4, f4, f4x4);
       
  3603 
       
  3604     // matrix * scalar
       
  3605     ADD_INTRINSIC_MATRIX_INT(add_intrinsic2(ctx, fn, dt, dt, dti));
       
  3606     ADD_INTRINSIC_MATRIX_FLOAT(add_intrinsic2(ctx, fn, dt, dt, dtf));
       
  3607 
       
  3608     // matrix * vector
       
  3609     add_intrinsic2(ctx, fn, i1, i1x1, i1);
       
  3610     add_intrinsic2(ctx, fn, i1, i1x2, i2);
       
  3611     add_intrinsic2(ctx, fn, i1, i1x3, i3);
       
  3612     add_intrinsic2(ctx, fn, i1, i1x4, i4);
       
  3613     add_intrinsic2(ctx, fn, i2, i2x1, i1);
       
  3614     add_intrinsic2(ctx, fn, i2, i2x2, i2);
       
  3615     add_intrinsic2(ctx, fn, i2, i2x3, i3);
       
  3616     add_intrinsic2(ctx, fn, i2, i2x4, i4);
       
  3617     add_intrinsic2(ctx, fn, i3, i3x1, i1);
       
  3618     add_intrinsic2(ctx, fn, i3, i3x2, i2);
       
  3619     add_intrinsic2(ctx, fn, i3, i3x3, i3);
       
  3620     add_intrinsic2(ctx, fn, i3, i3x4, i4);
       
  3621     add_intrinsic2(ctx, fn, i4, i4x1, i1);
       
  3622     add_intrinsic2(ctx, fn, i4, i4x2, i2);
       
  3623     add_intrinsic2(ctx, fn, i4, i4x3, i3);
       
  3624     add_intrinsic2(ctx, fn, i4, i4x4, i4);
       
  3625     add_intrinsic2(ctx, fn, f1, f1x1, f1);
       
  3626     add_intrinsic2(ctx, fn, f1, f1x2, f2);
       
  3627     add_intrinsic2(ctx, fn, f1, f1x3, f3);
       
  3628     add_intrinsic2(ctx, fn, f1, f1x4, f4);
       
  3629     add_intrinsic2(ctx, fn, f2, f2x1, f1);
       
  3630     add_intrinsic2(ctx, fn, f2, f2x2, f2);
       
  3631     add_intrinsic2(ctx, fn, f2, f2x3, f3);
       
  3632     add_intrinsic2(ctx, fn, f2, f2x4, f4);
       
  3633     add_intrinsic2(ctx, fn, f3, f3x1, f1);
       
  3634     add_intrinsic2(ctx, fn, f3, f3x2, f2);
       
  3635     add_intrinsic2(ctx, fn, f3, f3x3, f3);
       
  3636     add_intrinsic2(ctx, fn, f3, f3x4, f4);
       
  3637     add_intrinsic2(ctx, fn, f4, f4x1, f1);
       
  3638     add_intrinsic2(ctx, fn, f4, f4x2, f2);
       
  3639     add_intrinsic2(ctx, fn, f4, f4x3, f3);
       
  3640     add_intrinsic2(ctx, fn, f4, f4x4, f4);
       
  3641 
       
  3642     // matrix * matrix
       
  3643     add_intrinsic2(ctx, fn, i1x1, i1x1, i1x1);
       
  3644     add_intrinsic2(ctx, fn, i1x2, i1x1, i1x2);
       
  3645     add_intrinsic2(ctx, fn, i1x3, i1x1, i1x3);
       
  3646     add_intrinsic2(ctx, fn, i1x4, i1x1, i1x4);
       
  3647     add_intrinsic2(ctx, fn, i1x1, i1x2, i2x1);
       
  3648     add_intrinsic2(ctx, fn, i1x2, i1x2, i2x2);
       
  3649     add_intrinsic2(ctx, fn, i1x3, i1x2, i2x3);
       
  3650     add_intrinsic2(ctx, fn, i1x4, i1x2, i2x4);
       
  3651     add_intrinsic2(ctx, fn, i1x1, i1x3, i3x1);
       
  3652     add_intrinsic2(ctx, fn, i1x2, i1x3, i3x2);
       
  3653     add_intrinsic2(ctx, fn, i1x3, i1x3, i3x3);
       
  3654     add_intrinsic2(ctx, fn, i1x4, i1x3, i3x4);
       
  3655     add_intrinsic2(ctx, fn, i1x1, i1x4, i4x1);
       
  3656     add_intrinsic2(ctx, fn, i1x2, i1x4, i4x2);
       
  3657     add_intrinsic2(ctx, fn, i1x3, i1x4, i4x3);
       
  3658     add_intrinsic2(ctx, fn, i1x4, i1x4, i4x4);
       
  3659     add_intrinsic2(ctx, fn, i2x1, i2x1, i1x1);
       
  3660     add_intrinsic2(ctx, fn, i2x2, i2x1, i1x2);
       
  3661     add_intrinsic2(ctx, fn, i2x3, i2x1, i1x3);
       
  3662     add_intrinsic2(ctx, fn, i2x4, i2x1, i1x4);
       
  3663     add_intrinsic2(ctx, fn, i2x1, i2x2, i2x1);
       
  3664     add_intrinsic2(ctx, fn, i2x2, i2x2, i2x2);
       
  3665     add_intrinsic2(ctx, fn, i2x3, i2x2, i2x3);
       
  3666     add_intrinsic2(ctx, fn, i2x4, i2x2, i2x4);
       
  3667     add_intrinsic2(ctx, fn, i2x1, i2x3, i3x1);
       
  3668     add_intrinsic2(ctx, fn, i2x2, i2x3, i3x2);
       
  3669     add_intrinsic2(ctx, fn, i2x3, i2x3, i3x3);
       
  3670     add_intrinsic2(ctx, fn, i2x4, i2x3, i3x4);
       
  3671     add_intrinsic2(ctx, fn, i2x1, i2x4, i4x1);
       
  3672     add_intrinsic2(ctx, fn, i2x2, i2x4, i4x2);
       
  3673     add_intrinsic2(ctx, fn, i2x3, i2x4, i4x3);
       
  3674     add_intrinsic2(ctx, fn, i2x4, i2x4, i4x4);
       
  3675     add_intrinsic2(ctx, fn, i3x1, i3x1, i1x1);
       
  3676     add_intrinsic2(ctx, fn, i3x2, i3x1, i1x2);
       
  3677     add_intrinsic2(ctx, fn, i3x3, i3x1, i1x3);
       
  3678     add_intrinsic2(ctx, fn, i3x4, i3x1, i1x4);
       
  3679     add_intrinsic2(ctx, fn, i3x1, i3x2, i2x1);
       
  3680     add_intrinsic2(ctx, fn, i3x2, i3x2, i2x2);
       
  3681     add_intrinsic2(ctx, fn, i3x3, i3x2, i2x3);
       
  3682     add_intrinsic2(ctx, fn, i3x4, i3x2, i2x4);
       
  3683     add_intrinsic2(ctx, fn, i3x1, i3x3, i3x1);
       
  3684     add_intrinsic2(ctx, fn, i3x2, i3x3, i3x2);
       
  3685     add_intrinsic2(ctx, fn, i3x3, i3x3, i3x3);
       
  3686     add_intrinsic2(ctx, fn, i3x4, i3x3, i3x4);
       
  3687     add_intrinsic2(ctx, fn, i3x1, i3x4, i4x1);
       
  3688     add_intrinsic2(ctx, fn, i3x2, i3x4, i4x2);
       
  3689     add_intrinsic2(ctx, fn, i3x3, i3x4, i4x3);
       
  3690     add_intrinsic2(ctx, fn, i3x4, i3x4, i4x4);
       
  3691     add_intrinsic2(ctx, fn, i4x1, i4x1, i1x1);
       
  3692     add_intrinsic2(ctx, fn, i4x2, i4x1, i1x2);
       
  3693     add_intrinsic2(ctx, fn, i4x3, i4x1, i1x3);
       
  3694     add_intrinsic2(ctx, fn, i4x4, i4x1, i1x4);
       
  3695     add_intrinsic2(ctx, fn, i4x1, i4x2, i2x1);
       
  3696     add_intrinsic2(ctx, fn, i4x2, i4x2, i2x2);
       
  3697     add_intrinsic2(ctx, fn, i4x3, i4x2, i2x3);
       
  3698     add_intrinsic2(ctx, fn, i4x4, i4x2, i2x4);
       
  3699     add_intrinsic2(ctx, fn, i4x1, i4x3, i3x1);
       
  3700     add_intrinsic2(ctx, fn, i4x2, i4x3, i3x2);
       
  3701     add_intrinsic2(ctx, fn, i4x3, i4x3, i3x3);
       
  3702     add_intrinsic2(ctx, fn, i4x4, i4x3, i3x4);
       
  3703     add_intrinsic2(ctx, fn, i4x1, i4x4, i4x1);
       
  3704     add_intrinsic2(ctx, fn, i4x2, i4x4, i4x2);
       
  3705     add_intrinsic2(ctx, fn, i4x3, i4x4, i4x3);
       
  3706     add_intrinsic2(ctx, fn, i4x4, i4x4, i4x4);
       
  3707     add_intrinsic2(ctx, fn, f1x1, f1x1, f1x1);
       
  3708     add_intrinsic2(ctx, fn, f1x2, f1x1, f1x2);
       
  3709     add_intrinsic2(ctx, fn, f1x3, f1x1, f1x3);
       
  3710     add_intrinsic2(ctx, fn, f1x4, f1x1, f1x4);
       
  3711     add_intrinsic2(ctx, fn, f1x1, f1x2, f2x1);
       
  3712     add_intrinsic2(ctx, fn, f1x2, f1x2, f2x2);
       
  3713     add_intrinsic2(ctx, fn, f1x3, f1x2, f2x3);
       
  3714     add_intrinsic2(ctx, fn, f1x4, f1x2, f2x4);
       
  3715     add_intrinsic2(ctx, fn, f1x1, f1x3, f3x1);
       
  3716     add_intrinsic2(ctx, fn, f1x2, f1x3, f3x2);
       
  3717     add_intrinsic2(ctx, fn, f1x3, f1x3, f3x3);
       
  3718     add_intrinsic2(ctx, fn, f1x4, f1x3, f3x4);
       
  3719     add_intrinsic2(ctx, fn, f1x1, f1x4, f4x1);
       
  3720     add_intrinsic2(ctx, fn, f1x2, f1x4, f4x2);
       
  3721     add_intrinsic2(ctx, fn, f1x3, f1x4, f4x3);
       
  3722     add_intrinsic2(ctx, fn, f1x4, f1x4, f4x4);
       
  3723     add_intrinsic2(ctx, fn, f2x1, f2x1, f1x1);
       
  3724     add_intrinsic2(ctx, fn, f2x2, f2x1, f1x2);
       
  3725     add_intrinsic2(ctx, fn, f2x3, f2x1, f1x3);
       
  3726     add_intrinsic2(ctx, fn, f2x4, f2x1, f1x4);
       
  3727     add_intrinsic2(ctx, fn, f2x1, f2x2, f2x1);
       
  3728     add_intrinsic2(ctx, fn, f2x2, f2x2, f2x2);
       
  3729     add_intrinsic2(ctx, fn, f2x3, f2x2, f2x3);
       
  3730     add_intrinsic2(ctx, fn, f2x4, f2x2, f2x4);
       
  3731     add_intrinsic2(ctx, fn, f2x1, f2x3, f3x1);
       
  3732     add_intrinsic2(ctx, fn, f2x2, f2x3, f3x2);
       
  3733     add_intrinsic2(ctx, fn, f2x3, f2x3, f3x3);
       
  3734     add_intrinsic2(ctx, fn, f2x4, f2x3, f3x4);
       
  3735     add_intrinsic2(ctx, fn, f2x1, f2x4, f4x1);
       
  3736     add_intrinsic2(ctx, fn, f2x2, f2x4, f4x2);
       
  3737     add_intrinsic2(ctx, fn, f2x3, f2x4, f4x3);
       
  3738     add_intrinsic2(ctx, fn, f2x4, f2x4, f4x4);
       
  3739     add_intrinsic2(ctx, fn, f3x1, f3x1, f1x1);
       
  3740     add_intrinsic2(ctx, fn, f3x2, f3x1, f1x2);
       
  3741     add_intrinsic2(ctx, fn, f3x3, f3x1, f1x3);
       
  3742     add_intrinsic2(ctx, fn, f3x4, f3x1, f1x4);
       
  3743     add_intrinsic2(ctx, fn, f3x1, f3x2, f2x1);
       
  3744     add_intrinsic2(ctx, fn, f3x2, f3x2, f2x2);
       
  3745     add_intrinsic2(ctx, fn, f3x3, f3x2, f2x3);
       
  3746     add_intrinsic2(ctx, fn, f3x4, f3x2, f2x4);
       
  3747     add_intrinsic2(ctx, fn, f3x1, f3x3, f3x1);
       
  3748     add_intrinsic2(ctx, fn, f3x2, f3x3, f3x2);
       
  3749     add_intrinsic2(ctx, fn, f3x3, f3x3, f3x3);
       
  3750     add_intrinsic2(ctx, fn, f3x4, f3x3, f3x4);
       
  3751     add_intrinsic2(ctx, fn, f3x1, f3x4, f4x1);
       
  3752     add_intrinsic2(ctx, fn, f3x2, f3x4, f4x2);
       
  3753     add_intrinsic2(ctx, fn, f3x3, f3x4, f4x3);
       
  3754     add_intrinsic2(ctx, fn, f3x4, f3x4, f4x4);
       
  3755     add_intrinsic2(ctx, fn, f4x1, f4x1, f1x1);
       
  3756     add_intrinsic2(ctx, fn, f4x2, f4x1, f1x2);
       
  3757     add_intrinsic2(ctx, fn, f4x3, f4x1, f1x3);
       
  3758     add_intrinsic2(ctx, fn, f4x4, f4x1, f1x4);
       
  3759     add_intrinsic2(ctx, fn, f4x1, f4x2, f2x1);
       
  3760     add_intrinsic2(ctx, fn, f4x2, f4x2, f2x2);
       
  3761     add_intrinsic2(ctx, fn, f4x3, f4x2, f2x3);
       
  3762     add_intrinsic2(ctx, fn, f4x4, f4x2, f2x4);
       
  3763     add_intrinsic2(ctx, fn, f4x1, f4x3, f3x1);
       
  3764     add_intrinsic2(ctx, fn, f4x2, f4x3, f3x2);
       
  3765     add_intrinsic2(ctx, fn, f4x3, f4x3, f3x3);
       
  3766     add_intrinsic2(ctx, fn, f4x4, f4x3, f3x4);
       
  3767     add_intrinsic2(ctx, fn, f4x1, f4x4, f4x1);
       
  3768     add_intrinsic2(ctx, fn, f4x2, f4x4, f4x2);
       
  3769     add_intrinsic2(ctx, fn, f4x3, f4x4, f4x3);
       
  3770     add_intrinsic2(ctx, fn, f4x4, f4x4, f4x4);
       
  3771 } // add_intrinsic_mul
       
  3772 
       
  3773 static void init_builtins(Context *ctx)
       
  3774 {
  3241     // add in standard typedefs...
  3775     // add in standard typedefs...
  3242     const struct
  3776     const struct
  3243     {
  3777     {
  3244         const char *str;
  3778         const char *str;
  3245         const MOJOSHADER_astDataType *datatype;
  3779         const MOJOSHADER_astDataType *datatype;
  3273                 push_usertype(ctx, stringcache_len(ctx->strcache,buf,len), dt);
  3807                 push_usertype(ctx, stringcache_len(ctx->strcache,buf,len), dt);
  3274             } // for
  3808             } // for
  3275         } // for
  3809         } // for
  3276     } // for
  3810     } // for
  3277 
  3811 
       
  3812     // !!! FIXME: block these out by pixel/vertex/etc shader.
       
  3813     // !!! FIXME: calculate actual shader model (or maybe just let bytecode verifier throw up?).
       
  3814     const int shader_model = 3;
       
  3815     if (shader_model >= 1)
       
  3816     {
       
  3817         add_intrinsic_SAME1_ANYfi(ctx, stringcache(ctx->strcache, "abs"));
       
  3818         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "acos"));
       
  3819         add_intrinsic_BOOL_ANYfib(ctx, stringcache(ctx->strcache, "all"));
       
  3820         add_intrinsic_BOOL_ANYfib(ctx, stringcache(ctx->strcache, "any"));
       
  3821         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "asin"));
       
  3822         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "atan"));
       
  3823         add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "atan2"));
       
  3824         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "ceil"));
       
  3825         add_intrinsic_SAME1_ANYfi_SAME1_SAME1(ctx, stringcache(ctx->strcache, "clamp"));
       
  3826         add_intrinsic_VOID_ANYf(ctx, stringcache(ctx->strcache, "clip"));
       
  3827         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "cos"));
       
  3828         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "cosh"));
       
  3829         add_intrinsic_3f_3f_3f(ctx, stringcache(ctx->strcache, "cross"));
       
  3830         add_intrinsic_4i_4f(ctx, stringcache(ctx->strcache, "D3DCOLORtoUBYTE4"));
       
  3831         add_intrinsic_f_Vf_SAME1(ctx, stringcache(ctx->strcache, "distance"));
       
  3832         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "degrees"));
       
  3833         add_intrinsic_f_SQUAREMATRIXf(ctx, stringcache(ctx->strcache, "determinant"));
       
  3834         add_intrinsic_fi_Vfi_SAME1(ctx, stringcache(ctx->strcache, "dot"));
       
  3835         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "exp"));
       
  3836         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "exp2"));
       
  3837         add_intrinsic_SAME1_Vf_SAME1_SAME1(ctx, stringcache(ctx->strcache, "faceforward"));
       
  3838         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "floor"));
       
  3839         add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "fmod"));
       
  3840         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "frac"));
       
  3841         add_intrinsic_BOOL_ANYf(ctx, stringcache(ctx->strcache, "isfinite"));
       
  3842         add_intrinsic_BOOL_ANYf(ctx, stringcache(ctx->strcache, "isinf"));
       
  3843         add_intrinsic_BOOL_ANYf(ctx, stringcache(ctx->strcache, "isnan"));
       
  3844         add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "ldexp"));
       
  3845         add_intrinsic_f_Vf(ctx, stringcache(ctx->strcache, "length"));
       
  3846         add_intrinsic_SAME1_ANYf_SAME1_SAME1(ctx, stringcache(ctx->strcache, "lerp"));
       
  3847         add_intrinsic_4f_f_f_f(ctx, stringcache(ctx->strcache, "lit"));
       
  3848         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "log"));
       
  3849         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "log10"));
       
  3850         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "log2"));
       
  3851         add_intrinsic_SAME1_ANYfi_SAME1(ctx, stringcache(ctx->strcache, "max"));
       
  3852         add_intrinsic_SAME1_ANYfi_SAME1(ctx, stringcache(ctx->strcache, "min"));
       
  3853         add_intrinsic_SAME1_ANYfi_SAME1(ctx, stringcache(ctx->strcache, "modf"));  // !!! FIXME: out var?
       
  3854         add_intrinsic_mul(ctx, stringcache(ctx->strcache, "mul"));
       
  3855         add_intrinsic_f_Vf(ctx, stringcache(ctx->strcache, "noise"));
       
  3856         add_intrinsic_SAME1_Vf(ctx, stringcache(ctx->strcache, "normalize"));
       
  3857         add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "pow"));
       
  3858         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "radians"));
       
  3859         add_intrinsic_SAME1_ANYfi_SAME1(ctx, stringcache(ctx->strcache, "reflect"));
       
  3860         add_intrinsic_SAME1_Vf_SAME1_f(ctx, stringcache(ctx->strcache, "refract"));
       
  3861         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "round"));
       
  3862         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "rsqrt"));
       
  3863         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "saturate"));
       
  3864         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "sign"));
       
  3865         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "sin"));
       
  3866         add_intrinsic_VOID_ANYf_SAME1_SAME1(ctx, stringcache(ctx->strcache, "sincos"));  // !!! FIXME: out var?
       
  3867         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "sinh"));
       
  3868         add_intrinsic_SAME1_ANYf_SAME1_SAME1(ctx, stringcache(ctx->strcache, "smoothstep"));
       
  3869         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "sqrt"));
       
  3870         add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "step"));
       
  3871         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "tan"));
       
  3872         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "tanh"));
       
  3873         add_intrinsic_4f_s1_f(ctx, stringcache(ctx->strcache, "tex1D"));
       
  3874         add_intrinsic_4f_s2_2f(ctx, stringcache(ctx->strcache, "tex2D"));
       
  3875         add_intrinsic_4f_s3_3f(ctx, stringcache(ctx->strcache, "tex3D"));
       
  3876         add_intrinsic_4f_sc_3f(ctx, stringcache(ctx->strcache, "texCUBE"));
       
  3877         add_intrinsic_SAME1_Mfib(ctx, stringcache(ctx->strcache, "transpose"));
       
  3878         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "trunc"));
       
  3879     } // if
       
  3880 
       
  3881     if (shader_model >= 2)
       
  3882     {
       
  3883         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "ddx"));
       
  3884         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "ddy"));
       
  3885         add_intrinsic_SAME1_ANYf_SAME1(ctx, stringcache(ctx->strcache, "frexp"));
       
  3886         add_intrinsic_SAME1_ANYf(ctx, stringcache(ctx->strcache, "fwidth"));
       
  3887         add_intrinsic_4f_s1_f_f_f(ctx, stringcache(ctx->strcache, "tex1D"));
       
  3888         add_intrinsic_4f_s1_4f(ctx, stringcache(ctx->strcache, "tex1Dbias"));
       
  3889         add_intrinsic_4f_s1_f_f_f(ctx, stringcache(ctx->strcache, "tex1Dgrad"));
       
  3890         add_intrinsic_4f_s1_4f(ctx, stringcache(ctx->strcache, "tex1Dproj"));
       
  3891         add_intrinsic_4f_s2_2f_2f_2f(ctx, stringcache(ctx->strcache, "tex2D"));
       
  3892         add_intrinsic_4f_s2_4f(ctx, stringcache(ctx->strcache, "tex2Dbias"));
       
  3893         add_intrinsic_4f_s2_2f_2f_2f(ctx, stringcache(ctx->strcache, "tex2Dgrad"));
       
  3894         add_intrinsic_4f_s2_4f(ctx, stringcache(ctx->strcache, "tex2Dproj"));
       
  3895         add_intrinsic_4f_s3_3f_3f_3f(ctx, stringcache(ctx->strcache, "tex3D"));
       
  3896         add_intrinsic_4f_s3_4f(ctx, stringcache(ctx->strcache, "tex3Dbias"));
       
  3897         add_intrinsic_4f_s3_3f_3f_3f(ctx, stringcache(ctx->strcache, "tex3Dgrad"));
       
  3898         add_intrinsic_4f_s3_4f(ctx, stringcache(ctx->strcache, "tex3Dproj"));
       
  3899         add_intrinsic_4f_sc_3f_3f_3f(ctx, stringcache(ctx->strcache, "texCUBE"));
       
  3900         add_intrinsic_4f_sc_4f(ctx, stringcache(ctx->strcache, "texCUBEbias"));
       
  3901         add_intrinsic_4f_sc_3f_3f_3f(ctx, stringcache(ctx->strcache, "texCUBEgrad"));
       
  3902         add_intrinsic_4f_sc_4f(ctx, stringcache(ctx->strcache, "texCUBEproj"));
       
  3903     } // if
       
  3904 
       
  3905     if (shader_model >= 3)
       
  3906     {
       
  3907         add_intrinsic_4f_s1_4f(ctx, stringcache(ctx->strcache, "tex1Dlod"));
       
  3908         add_intrinsic_4f_s2_4f(ctx, stringcache(ctx->strcache, "tex2Dlod"));
       
  3909         add_intrinsic_4f_s3_4f(ctx, stringcache(ctx->strcache, "tex3Dlod"));
       
  3910         add_intrinsic_4f_sc_4f(ctx, stringcache(ctx->strcache, "texCUBElod"));
       
  3911     } // if
       
  3912 } // init_builtins
       
  3913 
       
  3914 
       
  3915 // parse the source code into an AST.
       
  3916 static void parse_source(Context *ctx, const char *filename,
       
  3917                          const char *source, unsigned int sourcelen,
       
  3918                          const MOJOSHADER_preprocessorDefine *defines,
       
  3919                          unsigned int define_count,
       
  3920                          MOJOSHADER_includeOpen include_open,
       
  3921                          MOJOSHADER_includeClose include_close)
       
  3922 {
       
  3923     TokenData data;
       
  3924     unsigned int tokenlen;
       
  3925     Token tokenval;
       
  3926     const char *token;
       
  3927     int lemon_token;
       
  3928     const char *fname;
       
  3929     Preprocessor *pp;
       
  3930     void *parser;
       
  3931 
       
  3932     if (!include_open) include_open = MOJOSHADER_internal_include_open;
       
  3933     if (!include_close) include_close = MOJOSHADER_internal_include_close;
       
  3934 
       
  3935     pp = preprocessor_start(filename, source, sourcelen, include_open,
       
  3936                             include_close, defines, define_count, 0,
       
  3937                             MallocBridge, FreeBridge, ctx);
       
  3938     if (pp == NULL)
       
  3939     {
       
  3940         assert(ctx->out_of_memory);  // shouldn't fail for any other reason.
       
  3941         return;
       
  3942     } // if
       
  3943 
       
  3944     parser = ParseHLSLAlloc(ctx->malloc, ctx->malloc_data);
       
  3945     if (parser == NULL)
       
  3946     {
       
  3947         assert(ctx->out_of_memory);  // shouldn't fail for any other reason.
       
  3948         preprocessor_end(pp);
       
  3949         return;
       
  3950     } // if
       
  3951 
       
  3952     // !!! FIXME: check if (parser == NULL)...
       
  3953 
       
  3954     init_builtins(ctx);
       
  3955 
       
  3956     SymbolScope *start_scope = ctx->usertypes.scope;
       
  3957 
       
  3958     #if DEBUG_COMPILER_PARSER
       
  3959     ParseHLSLTrace(stdout, "COMPILER: ");
       
  3960     #endif
       
  3961 
  3278     // Run the preprocessor/lexer/parser...
  3962     // Run the preprocessor/lexer/parser...
  3279     int is_pragma = 0;   // !!! FIXME: remove this later when we can parse #pragma.
  3963     int is_pragma = 0;   // !!! FIXME: remove this later when we can parse #pragma.
  3280     int skipping = 0; // !!! FIXME: remove this later when we can parse #pragma.
  3964     int skipping = 0; // !!! FIXME: remove this later when we can parse #pragma.
  3281     do {
  3965     do {
  3282         token = preprocessor_nexttoken(pp, &tokenlen, &tokenval);
  3966         token = preprocessor_nexttoken(pp, &tokenlen, &tokenval);