Changeset 883fedc in mainline


Ignore:
Timestamp:
2010-04-23T23:09:56Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
37c9fc8
Parents:
80badbe (diff), 6c39a907 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jsvoboda/helenos/sysel. New: generic classes, autoboxing, delegates.

Location:
uspace
Files:
5 added
39 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sbi/Makefile

    r80badbe r883fedc  
    3434
    3535SOURCES = \
     36        src/builtin/bi_boxed.c \
    3637        src/builtin/bi_error.c \
    3738        src/builtin/bi_fun.c \
  • uspace/app/sbi/src/builtin.c

    r80badbe r883fedc  
    4040#include <stdlib.h>
    4141#include <assert.h>
    42 #include "ancr.h"
     42#include "builtin/bi_boxed.h"
    4343#include "builtin/bi_error.h"
    4444#include "builtin/bi_fun.h"
     
    9090        bi_fun_declare(bi);
    9191        bi_textfile_declare(bi);
    92 
    93         /* Need to process ancestry so that symbol lookups work. */
    94         ancr_module_process(program, program->module);
    95 
     92}
     93
     94/** Bind internal interpreter references to symbols in the program.
     95 *
     96 * This is performed in separate phase for several reasons. First,
     97 * symbol lookups do not work until ancestry is processed. Second,
     98 * this gives a chance to process the library first and thus bind
     99 * to symbols defined there.
     100 */
     101void builtin_bind(builtin_t *bi)
     102{
     103        bi_boxed_bind(bi);
    96104        bi_error_bind(bi);
    97105        bi_fun_bind(bi);
     
    300308        stree_ident_t *ident;
    301309        stree_fun_t *fun;
     310        stree_fun_sig_t *sig;
    302311        stree_csimbr_t *csimbr;
    303312        stree_symbol_t *fun_sym;
     
    310319        fun->proc = stree_proc_new();
    311320        fun->proc->body = NULL;
    312         list_init(&fun->args);
     321        sig = stree_fun_sig_new();
     322        fun->sig = sig;
     323
     324        list_init(&fun->sig->args);
    313325
    314326        csimbr = stree_csimbr_new(csimbr_fun);
     
    348360        proc_arg->type = NULL; /* XXX */
    349361
    350         list_append(&fun->args, proc_arg);
    351 }
     362        list_append(&fun->sig->args, proc_arg);
     363}
  • uspace/app/sbi/src/builtin.h

    r80badbe r883fedc  
    3333
    3434void builtin_declare(stree_program_t *program);
     35void builtin_bind(builtin_t *bi);
    3536void builtin_code_snippet(builtin_t *bi, const char *snippet);
    3637
  • uspace/app/sbi/src/builtin/bi_error.c

    r80badbe r883fedc  
    3636#include "bi_error.h"
    3737
    38 /** Declare error class hierarchy. */
     38/** Declare error class hierarchy.
     39 *
     40 * @param bi    Builtin object
     41 */
    3942void bi_error_declare(builtin_t *bi)
    4043{
     
    5760                "end\n");}
    5861
    59 /** Bind error class hierarchy. */
     62/** Bind error class hierarchy.
     63 *
     64 * @param bi    Builtin object
     65 */
    6066void bi_error_bind(builtin_t *bi)
    6167{
  • uspace/app/sbi/src/builtin/bi_fun.c

    r80badbe r883fedc  
    4444#include "bi_fun.h"
    4545
     46static void bi_fun_builtin_write(run_t *run);
    4647static void bi_fun_builtin_writeline(run_t *run);
    4748static void bi_fun_task_exec(run_t *run);
    4849
    49 /** Declare builtin functions. */
     50/** Declare builtin functions.
     51 *
     52 * @param bi    Builtin object
     53 */
    5054void bi_fun_declare(builtin_t *bi)
    5155{
     
    6367        csi = stree_csi_new(csi_class);
    6468        csi->name = ident;
     69        list_init(&csi->targ);
    6570        list_init(&csi->members);
    6671
     
    7580        list_append(&bi->program->module->members, modm);
    7681
     82        /* Declare Builtin.Write(). */
     83
     84        fun_sym = builtin_declare_fun(csi, "Write");
     85        builtin_fun_add_arg(fun_sym, "arg");
     86
    7787        /* Declare Builtin.WriteLine(). */
    7888
     
    8898}
    8999
    90 /** Bind builtin functions. */
     100/** Bind builtin functions.
     101 *
     102 * @param bi    Builtin object
     103 */
    91104void bi_fun_bind(builtin_t *bi)
    92105{
     106        builtin_fun_bind(bi, "Builtin", "Write", bi_fun_builtin_write);
    93107        builtin_fun_bind(bi, "Builtin", "WriteLine", bi_fun_builtin_writeline);
    94108        builtin_fun_bind(bi, "Task", "Exec", bi_fun_task_exec);
    95109}
    96110
    97 /** Write a line of output. */
    98 static void bi_fun_builtin_writeline(run_t *run)
     111/** Write to the console.
     112 *
     113 * @param run   Runner object
     114 */
     115static void bi_fun_builtin_write(run_t *run)
    99116{
    100117        rdata_var_t *var;
     
    103120
    104121#ifdef DEBUG_RUN_TRACE
    105         printf("Called Builtin.WriteLine()\n");
     122        printf("Called Builtin.Write()\n");
    106123#endif
    107124        var = run_local_vars_lookup(run, strtab_get_sid("arg"));
     
    109126
    110127        switch (var->vc) {
     128        case vc_bool:
     129                printf("%s", var->u.bool_v->value ? "true" : "false");
     130                break;
    111131        case vc_char:
    112132                rc = bigint_get_value_int(&var->u.char_v->value, &char_val);
    113133                if (rc == EOK)
    114                         printf("%lc\n", char_val);
     134                        printf("%lc", char_val);
    115135                else
    116                         printf("???\n");
     136                        printf("???");
    117137                break;
    118138        case vc_int:
    119139                bigint_print(&var->u.int_v->value);
    120                 putchar('\n');
    121140                break;
    122141        case vc_string:
    123                 printf("%s\n", var->u.string_v->value);
     142                printf("%s", var->u.string_v->value);
    124143                break;
    125144        default:
    126                 printf("Unimplemented: writeLine() with unsupported type.\n");
    127                 exit(1);
    128         }
    129 }
    130 
    131 /** Start an executable and wait for it to finish. */
     145                printf("Unimplemented: Write() with unsupported type.\n");
     146                exit(1);
     147        }
     148}
     149
     150/** Write a line of output.
     151 *
     152 * @param run   Runner object
     153 */
     154static void bi_fun_builtin_writeline(run_t *run)
     155{
     156#ifdef DEBUG_RUN_TRACE
     157        printf("Called Builtin.WriteLine()\n");
     158#endif
     159        bi_fun_builtin_write(run);
     160        putchar('\n');
     161}
     162
     163/** Start an executable and wait for it to finish.
     164 *
     165 * @param run   Runner object
     166 */
    132167static void bi_fun_task_exec(run_t *run)
    133168{
     
    137172        rdata_var_t *arg;
    138173        int idx, dim;
    139         char **cmd;
     174        const char **cmd;
    140175
    141176#ifdef DEBUG_RUN_TRACE
     
    178213        cmd[dim] = '\0';
    179214
    180         if (os_exec(cmd) != EOK) {
     215        if (os_exec((char * const *)cmd) != EOK) {
    181216                printf("Error: Exec failed.\n");
    182217                exit(1);
  • uspace/app/sbi/src/builtin/bi_textfile.c

    r80badbe r883fedc  
    5353static void bi_textfile_is_eof(run_t *run);
    5454
    55 /** Declare TextFile builtin. */
     55/** Declare TextFile builtin.
     56 *
     57 * @param bi    Builtin object
     58 */
    5659void bi_textfile_declare(builtin_t *bi)
    5760{
     
    7982}
    8083
    81 /** Bind TextFile builtin. */
     84/** Bind TextFile builtin.
     85 *
     86 * @param bi    Builtin object
     87 */
    8288void bi_textfile_bind(builtin_t *bi)
    8389{
     
    9096}
    9197
    92 /** Open a text file for reading. */
     98/** Open a text file for reading.
     99 *
     100 * @param run   Runner object
     101 */
    93102static void bi_textfile_openread(run_t *run)
    94103{
    95104        rdata_var_t *fname_var;
    96         char *fname;
     105        const char *fname;
    97106        FILE *file;
    98107
     
    130139}
    131140
    132 /** Open a text file for writing. */
     141/** Open a text file for writing.
     142 *
     143 * @param run   Runner object
     144 */
    133145static void bi_textfile_openwrite(run_t *run)
    134146{
    135147        rdata_var_t *fname_var;
    136         char *fname;
     148        const char *fname;
    137149        FILE *file;
    138150
     
    170182}
    171183
    172 /** Close a text file. */
     184/** Close a text file.
     185 *
     186 * @param run   Runner object
     187 */
    173188static void bi_textfile_close(run_t *run)
    174189{
     
    205220
    206221
    207 /** Read one line from a text file. */
     222/** Read one line from a text file.
     223 *
     224 * @param run   Runner object
     225 */
    208226static void bi_textfile_readline(run_t *run)
    209227{
     
    272290}
    273291
    274 /** Write one line to a text file. */
     292/** Write one line to a text file.
     293 *
     294 * @param run   Runner object
     295 */
    275296static void bi_textfile_writeline(run_t *run)
    276297{
     
    278299        rdata_var_t *self_f_var;
    279300        rdata_var_t *line_var;
    280         char *line;
     301        const char *line;
    281302
    282303        run_proc_ar_t *proc_ar;
     
    312333}
    313334
    314 /** Return value of EOF flag. */
     335/** Return value of EOF flag.
     336 *
     337 * @param run   Runner object
     338 */
    315339static void bi_textfile_is_eof(run_t *run)
    316340{
  • uspace/app/sbi/src/builtin_t.h

    r80badbe r883fedc  
    4343        struct stree_symbol *gf_class;
    4444
    45         /** Error class for nil reference access. */
     45        /** Boxed variants of primitive types */
     46        struct stree_symbol *boxed_bool;
     47        struct stree_symbol *boxed_char;
     48        struct stree_symbol *boxed_int;
     49        struct stree_symbol *boxed_string;
     50
     51        /** Error class for nil reference access */
    4652        struct stree_csi *error_nilreference;
    4753
    48         /** Error class for out-of-bounds array access. */
     54        /** Error class for out-of-bounds array access */
    4955        struct stree_csi *error_outofbounds;
    5056} builtin_t;
  • uspace/app/sbi/src/debug.h

    r80badbe r883fedc  
    3434
    3535/**
    36  *Uncomment this to get extra verbose messages from parser's lexing
     36 * Uncomment this to get extra verbose messages from parser's lexing
    3737 * primitives.
    3838 */
  • uspace/app/sbi/src/imode.c

    r80badbe r883fedc  
    9898        ancr_module_process(program, program->module);
    9999
     100        /* Bind internal interpreter references to symbols. */
     101        builtin_bind(program->builtin);
     102
     103        /* Resolve ancestry. */
     104        ancr_module_process(program, program->module);
     105
    100106        /* Construct typing context. */
    101107        stype.program = program;
  • uspace/app/sbi/src/lex.c

    r80badbe r883fedc  
    8080        { lc_class,     "class" },
    8181        { lc_constructor,       "constructor" },
     82        { lc_deleg,     "deleg" },
    8283        { lc_do,        "do" },
    8384        { lc_else,      "else" },
     
    210211        switch (lem->lclass) {
    211212        case lc_ident:
    212                 printf("(%d)", lem->u.ident.sid);
     213                printf("('%s')", strtab_get_str(lem->u.ident.sid));
    213214                break;
    214215        case lc_lit_int:
  • uspace/app/sbi/src/lex_t.h

    r80badbe r883fedc  
    4949        lc_class,
    5050        lc_constructor,
     51        lc_deleg,
    5152        lc_do,
    5253        lc_else,
  • uspace/app/sbi/src/main.c

    r80badbe r883fedc  
    9292                return 1;
    9393
     94        /* Resolve ancestry. */
     95        ancr_module_process(program, program->module);
     96
     97        /* Bind internal interpreter references to symbols. */
     98        builtin_bind(program->builtin);
     99
    94100        /* Process all source files specified in command-line arguments. */
    95101        while (argc > 0) {
  • uspace/app/sbi/src/os/helenos.c

    r80badbe r883fedc  
    4848static tinput_t *tinput = NULL;
    4949
    50 /** Concatenate two strings. */
     50/** Concatenate two strings.
     51 *
     52 * @param a     First string
     53 * @param b     Second string
     54 * @return      New string, concatenation of @a a and @a b.
     55 */
    5156char *os_str_acat(const char *a, const char *b)
    5257{
     
    7075}
    7176
    72 /** Compare two strings. */
     77/** Compare two strings.
     78 *
     79 * @param a     First string
     80 * @param b     Second string
     81 * @return      Zero if equal, nonzero if not equal
     82 */
    7383int os_str_cmp(const char *a, const char *b)
    7484{
     
    7686}
    7787
    78 /** Return number of characters in string. */
     88/** Return number of characters in string.
     89 *
     90 * @param str   String
     91 * @return      Number of characters in @a str.
     92 */
    7993size_t os_str_length(const char *str)
    8094{
     
    8296}
    8397
    84 /** Duplicate string. */
     98/** Duplicate string.
     99 *
     100 * @param str   String
     101 * @return      New string, duplicate of @a str.
     102 */
    85103char *os_str_dup(const char *str)
    86104{
     
    88106}
    89107
    90 /** Get character from string at the given index. */
     108/** Get character from string at the given index.
     109 *
     110 * @param str           String
     111 * @param index         Character index (starting from zero).
     112 * @param out_char      Place to store character.
     113 * @return              EOK on success, EINVAL if index is out of bounds,
     114 *                      EIO on decoding error.
     115 */
    91116int os_str_get_char(const char *str, int index, int *out_char)
    92117{
     
    117142}
    118143
    119 /** Read one line of input from the user. */
     144/** Read one line of input from the user.
     145 *
     146 * @param ptr   Place to store pointer to new string.
     147 */
    120148int os_input_line(char **ptr)
    121149{
     
    148176}
    149177
    150 /** Simple command execution. */
     178/** Simple command execution.
     179 *
     180 * @param cmd   Command and arguments (NULL-terminated list of strings.)
     181 *              Command is present just one, not duplicated.
     182 */
    151183int os_exec(char *const cmd[])
    152184{
     
    168200}
    169201
    170 /** Store the executable file path via which we were executed. */
     202/** Store the executable file path via which we were executed.
     203 *
     204 * @param path  Executable path via which we were executed.
     205 */
    171206void os_store_ef_path(char *path)
    172207{
  • uspace/app/sbi/src/os/os.h

    r80badbe r883fedc  
    3737void os_input_disp_help(void);
    3838int os_input_line(char **ptr);
    39 int os_exec(char *const cmd[]);
     39int os_exec(char * const cmd[]);
    4040
    4141void os_store_ef_path(char *path);
  • uspace/app/sbi/src/os/posix.c

    r80badbe r883fedc  
    4747 * The string functions are in fact standard C, but would not work under
    4848 * HelenOS.
    49  */
    50 
    51 /** Concatenate two strings. */
     49 *
     50 * XXX String functions used here only work with 8-bit text encoding.
     51 */
     52
     53/** Concatenate two strings.
     54 *
     55 * @param a     First string
     56 * @param b     Second string
     57 * @return      New string, concatenation of @a a and @a b.
     58 */
    5259char *os_str_acat(const char *a, const char *b)
    5360{
     
    7178}
    7279
    73 /** Compare two strings. */
     80/** Compare two strings.
     81 *
     82 * @param a     First string
     83 * @param b     Second string
     84 * @return      Zero if equal, nonzero if not equal
     85 */
    7486int os_str_cmp(const char *a, const char *b)
    7587{
     
    7789}
    7890
    79 /** Return number of characters in string. */
     91/** Return number of characters in string.
     92 *
     93 * @param str   String
     94 * @return      Number of characters in @a str.
     95 */
    8096size_t os_str_length(const char *str)
    8197{
     
    8399}
    84100
    85 /** Duplicate string. */
     101/** Duplicate string.
     102 *
     103 * @param str   String
     104 * @return      New string, duplicate of @a str.
     105 */
    86106char *os_str_dup(const char *str)
    87107{
     
    89109}
    90110
    91 /** Get character from string at the given index. */
     111/** Get character from string at the given index.
     112 *
     113 * @param str           String
     114 * @param index         Character index (starting from zero).
     115 * @param out_char      Place to store character.
     116 * @return              EOK on success, EINVAL if index is out of bounds,
     117 *                      EIO on decoding error.
     118 */
    92119int os_str_get_char(const char *str, int index, int *out_char)
    93120{
     
    111138}
    112139
    113 /** Read one line of input from the user. */
     140/** Read one line of input from the user.
     141 *
     142 * @param ptr   Place to store pointer to new string.
     143 */
    114144int os_input_line(char **ptr)
    115145{
     
    126156}
    127157
    128 /** Simple command execution. */
     158/** Simple command execution.
     159 *
     160 * @param cmd   Command and arguments (NULL-terminated list of strings.)
     161 *              Command is present just one, not duplicated.
     162 */
    129163int os_exec(char *const cmd[])
    130164{
     
    157191}
    158192
    159 /** Store the executable file path via which we were executed. */
     193/** Store the executable file path via which we were executed.
     194 *
     195 * @param path  Executable path via which we were executed.
     196 */
    160197void os_store_ef_path(char *path)
    161198{
  • uspace/app/sbi/src/parse.c

    r80badbe r883fedc  
    5454static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi);
    5555
     56static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi);
    5657static stree_fun_t *parse_fun(parse_t *parse, stree_csi_t *outer_csi);
    5758static stree_var_t *parse_var(parse_t *parse, stree_csi_t *outer_csi);
     
    6263static stree_proc_arg_t *parse_proc_arg(parse_t *parse);
    6364static stree_arg_attr_t *parse_arg_attr(parse_t *parse);
     65static stree_fun_sig_t *parse_fun_sig(parse_t *parse);
     66
    6467
    6568/*
     
    157160        stree_symbol_t *symbol;
    158161        stree_ident_t *targ_name;
     162        stree_targ_t *targ;
    159163
    160164        switch (dclass) {
     
    170174        csi->name = parse_ident(parse);
    171175
    172         list_init(&csi->targ_names);
     176        list_init(&csi->targ);
    173177
    174178        while (lcur_lc(parse) == lc_slash) {
    175179                lskip(parse);
    176180                targ_name = parse_ident(parse);
    177                 list_append(&csi->targ_names, targ_name);
     181
     182                targ = stree_targ_new();
     183                targ->name = targ_name;
     184
     185                list_append(&csi->targ, targ);
    178186        }
    179187
     
    201209        while (lcur_lc(parse) != lc_end && !parse_is_error(parse)) {
    202210                csimbr = parse_csimbr(parse, csi);
     211                if (csimbr == NULL)
     212                        break;
     213
    203214                list_append(&csi->members, csimbr);
    204215        }
     
    213224 * @param parse         Parser object.
    214225 * @param outer_csi     CSI containing this declaration or @c NULL if global.
    215  * @return              New syntax tree node.
     226 * @return              New syntax tree node. In case of parse error,
     227 *                      @c NULL may (but need not) be returned.
    216228 */
    217229static stree_csimbr_t *parse_csimbr(parse_t *parse, stree_csi_t *outer_csi)
     
    220232
    221233        stree_csi_t *csi;
     234        stree_deleg_t *deleg;
    222235        stree_fun_t *fun;
    223236        stree_var_t *var;
     
    232245                csimbr->u.csi = csi;
    233246                break;
     247        case lc_deleg:
     248                deleg = parse_deleg(parse, outer_csi);
     249                csimbr = stree_csimbr_new(csimbr_deleg);
     250                csimbr->u.deleg = deleg;
     251                break;
    234252        case lc_fun:
    235253                fun = parse_fun(parse, outer_csi);
     
    250268                lunexpected_error(parse);
    251269                lex_next(parse->lex);
     270                csimbr = NULL;
     271                break;
    252272        }
    253273
     
    255275}
    256276
     277/** Parse delegate.
     278 *
     279 * @param parse         Parser object.
     280 * @param outer_csi     CSI containing this declaration or @c NULL if global.
     281 * @return              New syntax tree node.
     282 */
     283static stree_deleg_t *parse_deleg(parse_t *parse, stree_csi_t *outer_csi)
     284{
     285        stree_deleg_t *deleg;
     286        stree_symbol_t *symbol;
     287        stree_symbol_attr_t *attr;
     288
     289        deleg = stree_deleg_new();
     290        symbol = stree_symbol_new(sc_deleg);
     291
     292        symbol->u.deleg = deleg;
     293        symbol->outer_csi = outer_csi;
     294        deleg->symbol = symbol;
     295
     296        lmatch(parse, lc_deleg);
     297        deleg->name = parse_ident(parse);
     298
     299#ifdef DEBUG_PARSE_TRACE
     300        printf("Parsing delegate '%s'.\n", strtab_get_str(deleg->name->sid));
     301#endif
     302
     303        deleg->sig = parse_fun_sig(parse);
     304
     305        list_init(&symbol->attr);
     306
     307        /* Parse attributes. */
     308        while (lcur_lc(parse) == lc_comma && !parse_is_error(parse)) {
     309                lskip(parse);
     310                attr = parse_symbol_attr(parse);
     311                list_append(&symbol->attr, attr);
     312        }
     313
     314        lmatch(parse, lc_scolon);
     315
     316        return deleg;
     317}
    257318
    258319/** Parse member function.
     
    265326{
    266327        stree_fun_t *fun;
    267         stree_proc_arg_t *arg;
    268328        stree_symbol_t *symbol;
    269329        stree_symbol_attr_t *attr;
     
    278338        lmatch(parse, lc_fun);
    279339        fun->name = parse_ident(parse);
    280         lmatch(parse, lc_lparen);
    281340
    282341#ifdef DEBUG_PARSE_TRACE
    283342        printf("Parsing function '%s'.\n", strtab_get_str(fun->name->sid));
    284343#endif
    285 
    286         list_init(&fun->args);
    287 
    288         if (lcur_lc(parse) != lc_rparen) {
    289 
    290                 /* Parse formal parameters. */
    291                 while (!parse_is_error(parse)) {
    292                         arg = parse_proc_arg(parse);
    293 
    294                         if (stree_arg_has_attr(arg, aac_packed)) {
    295                                 fun->varg = arg;
    296                                 break;
    297                         } else {
    298                                 list_append(&fun->args, arg);
    299                         }
    300 
    301                         if (lcur_lc(parse) == lc_rparen)
    302                                 break;
    303 
    304                         lmatch(parse, lc_scolon);
    305                 }
    306         }
    307 
    308         lmatch(parse, lc_rparen);
    309 
    310         if (lcur_lc(parse) == lc_colon) {
    311                 lskip(parse);
    312                 fun->rtype = parse_texpr(parse);
    313         } else {
    314                 fun->rtype = NULL;
    315         }
     344        fun->sig = parse_fun_sig(parse);
    316345
    317346        list_init(&symbol->attr);
     
    522551        arg->type = parse_texpr(parse);
    523552
    524         list_init(&arg->attr);
     553#ifdef DEBUG_PARSE_TRACE
     554        printf("Parse procedure argument.\n");
     555#endif
     556        list_init(&arg->attr);
    525557
    526558        /* Parse attributes. */
     
    531563        }
    532564
    533 #ifdef DEBUG_PARSE_TRACE
    534         printf("Parsed arg attr, type=%p.\n", arg->type);
    535 #endif
    536565        return arg;
    537566}
     
    557586        attr = stree_arg_attr_new(aac_packed);
    558587        return attr;
     588}
     589
     590/** Parse function signature.
     591 *
     592 * @param parse         Parser object.
     593 * @return              New syntax tree node.
     594 */
     595static stree_fun_sig_t *parse_fun_sig(parse_t *parse)
     596{
     597        stree_fun_sig_t *sig;
     598        stree_proc_arg_t *arg;
     599
     600        sig = stree_fun_sig_new();
     601
     602        lmatch(parse, lc_lparen);
     603
     604#ifdef DEBUG_PARSE_TRACE
     605        printf("Parsing function signature.\n");
     606#endif
     607
     608        list_init(&sig->args);
     609
     610        if (lcur_lc(parse) != lc_rparen) {
     611
     612                /* Parse formal parameters. */
     613                while (!parse_is_error(parse)) {
     614                        arg = parse_proc_arg(parse);
     615
     616                        if (stree_arg_has_attr(arg, aac_packed)) {
     617                                sig->varg = arg;
     618                                break;
     619                        } else {
     620                                list_append(&sig->args, arg);
     621                        }
     622
     623                        if (lcur_lc(parse) == lc_rparen)
     624                                break;
     625
     626                        lmatch(parse, lc_scolon);
     627                }
     628        }
     629
     630        lmatch(parse, lc_rparen);
     631
     632        if (lcur_lc(parse) == lc_colon) {
     633                lskip(parse);
     634                sig->rtype = parse_texpr(parse);
     635        } else {
     636                sig->rtype = NULL;
     637        }
     638
     639        return sig;
    559640}
    560641
  • uspace/app/sbi/src/rdata.c

    r80badbe r883fedc  
    529529static void rdata_deleg_copy(rdata_deleg_t *src, rdata_deleg_t **dest)
    530530{
    531         (void) src; (void) dest;
    532         printf("Unimplemented: Copy delegate.\n");
    533         exit(1);
     531        *dest = rdata_deleg_new();
     532        (*dest)->obj = src->obj;
     533        (*dest)->sym = src->sym;
    534534}
    535535
     
    711711                break;
    712712        case vc_ref:
    713                 printf("ref(");
    714                 rdata_var_print(var->u.ref_v->vref);
    715                 printf(")");
     713                if (var->u.ref_v->vref != NULL) {
     714                        printf("ref(");
     715                        rdata_var_print(var->u.ref_v->vref);
     716                        printf(")");
     717                } else {
     718                        printf("nil");
     719                }
    716720                break;
    717721        case vc_deleg:
    718722                printf("deleg(");
    719                 if (var->u.deleg_v->obj != NULL) {
    720                         rdata_var_print(var->u.deleg_v->obj);
    721                         printf(",");
     723                if (var->u.deleg_v->sym != NULL) {
     724                        if (var->u.deleg_v->obj != NULL) {
     725                                rdata_var_print(var->u.deleg_v->obj);
     726                                printf(",");
     727                        }
     728                        symbol_print_fqn(var->u.deleg_v->sym);
     729                } else {
     730                        printf("nil");
    722731                }
    723                 symbol_print_fqn(var->u.deleg_v->sym);
    724732                printf(")");
    725733                break;
  • uspace/app/sbi/src/rdata_t.h

    r80badbe r883fedc  
    6060/** String variable */
    6161typedef struct {
    62         char *value;
     62        const char *value;
    6363} rdata_string_t;
    6464
  • uspace/app/sbi/src/run.c

    r80badbe r883fedc  
    6767    rdata_value_t *value);
    6868
    69 /** Initialize runner instance. */
     69static void run_var_new_tprimitive(run_t *run, tdata_primitive_t *tprimitive,
     70    rdata_var_t **rvar);
     71static void run_var_new_null_ref(run_t *run, rdata_var_t **rvar);
     72static void run_var_new_deleg(run_t *run, rdata_var_t **rvar);
     73
     74
     75/** Initialize runner instance.
     76 *
     77 * @param run           Runner object
     78 */
    7079void run_init(run_t *run)
    7180{
     
    7382}
    7483
    75 /** Run program */
     84/** Run program.
     85 *
     86 * Associates the program @a prog with the runner object and executes
     87 * it. If a run-time error occurs during the execution (e.g. an unhandled
     88 * exception), @a run->error will be set to @c b_true when this function
     89 * returns.
     90 *
     91 * @param run           Runner object
     92 * @param prog          Program to run
     93 */
    7694void run_program(run_t *run, stree_program_t *prog)
    7795{
     
    119137}
    120138
    121 /** Run procedure. */
     139/** Run procedure.
     140 *
     141 * Inserts the provided procedure AR @a proc_ar on the execution stack
     142 * (in the thread AR) and executes the procedure. The return value
     143 * of the procedure is stored to *(@a res). @c NULL is stored if the
     144 * procedure returns no value.
     145 *
     146 * If the procedure execution bails out due to an exception, this
     147 * can be determined by looking at @c bo_mode in thread AR. Also,
     148 * in this case @c NULL is stored into *(@a res).
     149 *
     150 * @param run           Runner object
     151 * @param proc_ar       Procedure activation record
     152 * @param res           Place to store procedure return value
     153 */
    122154void run_proc(run_t *run, run_proc_ar_t *proc_ar, rdata_item_t **res)
    123155{
     
    171203}
    172204
    173 /** Run code block */
     205/** Run code block.
     206 *
     207 * @param run           Runner object
     208 * @param block         Block to run
     209 */
    174210static void run_block(run_t *run, stree_block_t *block)
    175211{
     
    218254 * @a res.
    219255 *
    220  * @param run   Runner object.
    221  * @param stat  Statement to run.
    222  * @param res   Place to store exps result or NULL if not interested.
     256 * @param run   Runner object
     257 * @param stat  Statement to run
     258 * @param res   Place to store exps result or NULL if not interested
    223259 */
    224260void run_stat(run_t *run, stree_stat_t *stat, rdata_item_t **res)
     
    266302 * of the expression (or NULL if it has no value) will be stored to @a res.
    267303 *
    268  * @param run   Runner object.
    269  * @param exps  Expression statement to run.
    270  * @param res   Place to store exps result or NULL if not interested.
     304 * @param run   Runner object
     305 * @param exps  Expression statement to run
     306 * @param res   Place to store exps result or NULL if not interested
    271307 */
    272308static void run_exps(run_t *run, stree_exps_t *exps, rdata_item_t **res)
     
    283319}
    284320
    285 /** Run variable declaration statement. */
     321/** Run variable declaration statement.
     322 *
     323 * @param run   Runner object
     324 * @param vdecl Variable declaration statement to run
     325 */
    286326static void run_vdecl(run_t *run, stree_vdecl_t *vdecl)
    287327{
    288328        run_block_ar_t *block_ar;
    289329        rdata_var_t *var, *old_var;
    290         rdata_int_t *int_v;
     330        tdata_item_t *var_ti;
    291331
    292332#ifdef DEBUG_RUN_TRACE
    293333        printf("Executing variable declaration statement.\n");
    294334#endif
    295 
    296         /* XXX Need to support other variables than int. */
    297 
    298         var = rdata_var_new(vc_int);
    299         int_v = rdata_int_new();
    300 
    301         var->u.int_v = int_v;
    302         bigint_init(&int_v->value, 0);
     335        /* Compute variable type. XXX Memoize. */
     336        run_texpr(run->program, run_get_current_csi(run), vdecl->type,
     337            &var_ti);
     338
     339        /* Create variable and initialize with default value. */
     340        run_var_new(run, var_ti, &var);
    303341
    304342        block_ar = run_get_current_block_ar(run);
     
    318356}
    319357
    320 /** Run @c if statement. */
     358/** Run @c if statement.
     359 *
     360 * @param run   Runner object
     361 * @param if_s  If statement to run
     362 */
    321363static void run_if(run_t *run, stree_if_t *if_s)
    322364{
     
    348390}
    349391
    350 /** Run @c while statement. */
     392/** Run @c while statement.
     393 *
     394 * @param run           Runner object
     395 * @param while_s       While statement to run
     396 */
    351397static void run_while(run_t *run, stree_while_t *while_s)
    352398{
     
    375421}
    376422
    377 /** Run @c raise statement. */
     423/** Run @c raise statement.
     424 *
     425 * @param run           Runner object
     426 * @param raise_s       Raise statement to run
     427 */
    378428static void run_raise(run_t *run, stree_raise_t *raise_s)
    379429{
     
    397447}
    398448
    399 /** Run @c return statement. */
     449/** Run @c return statement.
     450 *
     451 * Sets the return value in procedure AR and forces control to return
     452 * from the function by setting bailout mode to @c bm_proc.
     453 *
     454 * @param run           Runner object
     455 * @param raise_s       Return statement to run
     456 */
    400457static void run_return(run_t *run, stree_return_t *return_s)
    401458{
     
    413470        run_cvt_value_item(run, rexpr, &rexpr_vi);
    414471
    415         /* Store expression result in function AR. */
     472        /* Store expression result in procedure AR. */
    416473        proc_ar = run_get_current_proc_ar(run);
    417474        proc_ar->retval = rexpr_vi;
     
    422479}
    423480
    424 /** Run @c with-except-finally statement. */
     481/** Run @c with-except-finally statement.
     482 *
     483 * Note: 'With' clause is not implemented.
     484 *
     485 * @param run           Runner object
     486 * @param wef_s         With-except-finally statement to run
     487 */
    425488static void run_wef(run_t *run, stree_wef_t *wef_s)
    426489{
     
    489552 * matches except clause @c except_c.
    490553 *
    491  * @param run           Runner object.
    492  * @param except_c      @c except clause.
    493  * @return              @c b_true if there is a match, @c b_false otherwise.
     554 * @param run           Runner object
     555 * @param except_c      @c except clause
     556 * @return              @c b_true if there is a match, @c b_false otherwise
    494557 */
    495558static bool_t run_exc_match(run_t *run, stree_except_t *except_c)
     
    506569
    507570        /* Determine if active exc. is derived from type in exc. clause. */
     571        /* XXX This is wrong, it does not work with generics. */
    508572        return tdata_is_csi_derived_from_ti(exc_csi, etype);
    509573}
     
    511575/** Return CSI of the active exception.
    512576 *
    513  * @param run           Runner object.
    514  * @return              CSI of the active exception.
     577 * @param run           Runner object
     578 * @return              CSI of the active exception
    515579 */
    516580static stree_csi_t *run_exc_payload_get_csi(run_t *run)
     
    557621 * error message and raises a run-time error.
    558622 *
    559  * @param run           Runner object.
     623 * @param run           Runner object
    560624 */
    561625void run_exc_check_unhandled(run_t *run)
     
    579643 *
    580644 * Raises an error that cannot be handled by the user program.
     645 *
     646 * @param run           Runner object
    581647 */
    582648void run_raise_error(run_t *run)
     
    586652}
    587653
    588 /** Construct a special recovery item. */
     654/** Construct a special recovery item.
     655 *
     656 * @param run           Runner object
     657 */
    589658rdata_item_t *run_recovery_item(run_t *run)
    590659{
     
    593662}
    594663
    595 /** Find a local variable in the currently active function. */
     664/** Find a local variable in the currently active function.
     665 *
     666 * @param run           Runner object
     667 * @param name          Name SID of the local variable
     668 * @return              Pointer to var node or @c NULL if not found
     669 */
    596670rdata_var_t *run_local_vars_lookup(run_t *run, sid_t name)
    597671{
     
    618692}
    619693
    620 /** Get current function activation record. */
     694/** Get current procedure activation record.
     695 *
     696 * @param run           Runner object
     697 * @return              Active procedure AR
     698 */
    621699run_proc_ar_t *run_get_current_proc_ar(run_t *run)
    622700{
     
    627705}
    628706
    629 /** Get current block activation record. */
     707/** Get current block activation record.
     708 *
     709 * @param run           Runner object
     710 * @return              Active block AR
     711 */
    630712run_block_ar_t *run_get_current_block_ar(run_t *run)
    631713{
     
    639721}
    640722
    641 /** Get current CSI. */
     723/** Get current CSI.
     724 *
     725 * @param run           Runner object
     726 * @return              Active CSI
     727 */
    642728stree_csi_t *run_get_current_csi(run_t *run)
    643729{
     
    654740 * (1) Create a variable of the desired type.
    655741 * (2) Initialize the variable with the provided value.
     742 *
     743 * @param item          Value item (initial value for variable).
     744 * @param var           Place to store new var node.
    656745 */
    657746void run_value_item_to_var(rdata_item_t *item, rdata_var_t **var)
    658747{
     748        rdata_bool_t *bool_v;
    659749        rdata_char_t *char_v;
     750        rdata_deleg_t *deleg_v;
    660751        rdata_int_t *int_v;
    661752        rdata_string_t *string_v;
     
    667758
    668759        switch (in_var->vc) {
     760        case vc_bool:
     761                *var = rdata_var_new(vc_bool);
     762                bool_v = rdata_bool_new();
     763
     764                (*var)->u.bool_v = bool_v;
     765                bool_v->value = item->u.value->var->u.bool_v->value;
     766                break;
    669767        case vc_char:
    670768                *var = rdata_var_new(vc_char);
     
    675773                    &char_v->value);
    676774                break;
     775        case vc_deleg:
     776                *var = rdata_var_new(vc_deleg);
     777                deleg_v = rdata_deleg_new();
     778
     779                (*var)->u.deleg_v = deleg_v;
     780                deleg_v->obj = item->u.value->var->u.deleg_v->obj;
     781                deleg_v->sym = item->u.value->var->u.deleg_v->sym;
     782                break;
    677783        case vc_int:
    678784                *var = rdata_var_new(vc_int);
     
    704810}
    705811
    706 /** Construct a function AR. */
     812/** Construct a procedure AR.
     813 *
     814 * @param run           Runner object
     815 * @param obj           Object whose procedure is being activated
     816 * @param proc          Procedure that is being activated
     817 * @param rproc_ar      Place to store pointer to new activation record
     818 */
    707819void run_proc_ar_create(run_t *run, rdata_var_t *obj, stree_proc_t *proc,
    708820    run_proc_ar_t **rproc_ar)
     
    733845 * When invoking a procedure this is used to store the argument values
    734846 * in the activation record.
     847 *
     848 * @param run           Runner object
     849 * @param proc_ar       Existing procedure activation record where to store
     850 *                      the values
     851 * @param arg_vals      List of value items (rdata_item_t *) -- real
     852 *                      argument values
    735853 */
    736854void run_proc_ar_set_args(run_t *run, run_proc_ar_t *proc_ar, list_t *arg_vals)
     
    767885        case sc_fun:
    768886                fun = symbol_to_fun(outer_symbol);
    769                 args = &fun->args;
    770                 varg = fun->varg;
     887                args = &fun->sig->args;
     888                varg = fun->sig->varg;
    771889                break;
    772890        case sc_prop:
     
    865983 * When invoking a setter this is used to store its argument value in its
    866984 * procedure activation record.
     985 *
     986 * @param run           Runner object
     987 * @param proc_ar       Existing procedure activation record where to store
     988 *                      the setter argument
     989 * @param arg_val       Value items (rdata_item_t *) -- real argument value
    867990 */
    868991void run_proc_ar_set_setter_arg(run_t *run, run_proc_ar_t *proc_ar,
     
    8981021}
    8991022
    900 /** Print function activation backtrace. */
     1023/** Print function activation backtrace.
     1024 *
     1025 * Prints a backtrace of activated functions for debugging purposes.
     1026 *
     1027 * @param run           Runner object
     1028 */
    9011029void run_print_fun_bt(run_t *run)
    9021030{
     
    9201048 * If @a item is a value, we just return a copy. If @a item is an address,
    9211049 * we read from the address.
     1050 *
     1051 * @param run           Runner object
     1052 * @param item          Input item (value or address)
     1053 * @param ritem         Place to store pointer to new value item
    9221054 */
    9231055void run_cvt_value_item(run_t *run, rdata_item_t *item, rdata_item_t **ritem)
     
    9511083 * Get var-class of @a item, regardless whether it is a value or address.
    9521084 * (I.e. the var class of the value or variable at the given address).
     1085 *
     1086 * @param run           Runner object
     1087 * @param item          Value or address item
     1088 * @return              Varclass of @a item
    9531089 */
    9541090var_class_t run_item_get_vc(run_t *run, rdata_item_t *item)
     
    9921128 * copy.
    9931129 *
    994  * @param run   Runner object.
    995  * @param addr  Address of class @c ac_prop.
    996  * @param       Pointer to var node.
     1130 * @param run   Runner object
     1131 * @param addr  Address of class @c ac_prop
     1132 * @return      Pointer to var node
    9971133 */
    9981134static rdata_var_t *run_aprop_get_tpos(run_t *run, rdata_address_t *addr)
     
    10151151/** Read data from an address.
    10161152 *
    1017  * Return value stored in a variable at the specified address.
     1153 * Read value from the specified address.
     1154 *
     1155 * @param run           Runner object
     1156 * @param address       Address to read
     1157 * @param ritem         Place to store pointer to the value that was read
    10181158 */
    10191159void run_address_read(run_t *run, rdata_address_t *address,
     
    10361176/** Write data to an address.
    10371177 *
    1038  * Store @a value to the variable at @a address.
     1178 * Store value @a value at address @a address.
     1179 *
     1180 * @param run           Runner object
     1181 * @param address       Address to write
     1182 * @param value         Value to store at the address
    10391183 */
    10401184void run_address_write(run_t *run, rdata_address_t *address,
     
    10531197}
    10541198
     1199/** Read data from a property address.
     1200 *
     1201 * This involves invoking the property getter procedure.
     1202 *
     1203 * @param run           Runner object.
     1204 * @param addr_prop     Property address to read.
     1205 * @param ritem         Place to store pointer to the value that was read.
     1206 */
    10551207static void run_aprop_read(run_t *run, rdata_addr_prop_t *addr_prop,
    10561208    rdata_item_t **ritem)
     
    11161268}
    11171269
     1270/** Write data to a property address.
     1271 *
     1272 * This involves invoking the property setter procedure.
     1273 *
     1274 * @param run           Runner object
     1275 * @param addr_prop     Property address to write
     1276 * @param value         Value to store at the address
     1277 */
    11181278static void run_aprop_write(run_t *run, rdata_addr_prop_t *addr_prop,
    11191279    rdata_value_t *value)
     
    11811341 *
    11821342 * Constructs a reference (value item) pointing to @a var.
     1343 *
     1344 * @param run           Runner object
     1345 * @param var           Variable node that is being referenced
     1346 * @param res           Place to store pointer to new reference.
    11831347 */
    11841348void run_reference(run_t *run, rdata_var_t *var, rdata_item_t **res)
     
    12101374 * Takes a reference (address or value) and returns the address (item) of
    12111375 * the target of the reference.
     1376 *
     1377 * @param run           Runner object
     1378 * @param ref           Reference
     1379 * @param rtitem        Place to store pointer to the resulting address.
    12121380 */
    12131381void run_dereference(run_t *run, rdata_item_t *ref, rdata_item_t **ritem)
     
    12521420 * error (not for the @c raise statement).
    12531421 *
    1254  * @param run           Runner object.
    1255  * @param csi           Exception class.
     1422 * @param run           Runner object
     1423 * @param csi           Exception class
    12561424 */
    12571425void run_raise_exc(run_t *run, stree_csi_t *csi)
     
    12701438}
    12711439
    1272 /** Determine if we are bailing out. */
     1440/** Determine if we are bailing out.
     1441 *
     1442 * @param run           Runner object
     1443 * @return              @c b_true if we are bailing out, @c b_false otherwise
     1444 */
    12731445bool_t run_is_bo(run_t *run)
    12741446{
     
    12761448}
    12771449
     1450/** Construct a new variable of the given type.
     1451 *
     1452 * The variable is allocated and initialized with a default value
     1453 * based on type item @a ti. For reference types the default value
     1454 * is a null reference. At this point this does not work for generic
     1455 * types (we need RTTI).
     1456 *
     1457 * @param run           Runner object
     1458 * @param ti            Type of variable to create (type item)
     1459 * @param rvar          Place to store pointer to new variable
     1460 */
     1461void run_var_new(run_t *run, tdata_item_t *ti, rdata_var_t **rvar)
     1462{
     1463        rdata_var_t *var;
     1464
     1465        switch (ti->tic) {
     1466        case tic_tprimitive:
     1467                run_var_new_tprimitive(run, ti->u.tprimitive, rvar);
     1468                break;
     1469        case tic_tobject:
     1470        case tic_tarray:
     1471                run_var_new_null_ref(run, rvar);
     1472                break;
     1473        case tic_tdeleg:
     1474        case tic_tfun:
     1475                run_var_new_deleg(run, rvar);
     1476                break;
     1477        case tic_tvref:
     1478                /*
     1479                 * XXX Need to obtain run-time value of type argument to
     1480                 * initialize variable properly.
     1481                 */
     1482                var = rdata_var_new(vc_int);
     1483                var->u.int_v = rdata_int_new();
     1484                bigint_init(&var->u.int_v->value, 0);
     1485                *rvar = var;
     1486                break;
     1487        case tic_ignore:
     1488                assert(b_false);
     1489        }
     1490}
     1491
     1492/** Construct a new variable of primitive type.
     1493 *
     1494 * The variable is allocated and initialized with a default value
     1495 * based on primitive type item @a tprimitive.
     1496 *
     1497 * @param run           Runner object
     1498 * @param ti            Primitive type of variable to create
     1499 * @param rvar          Place to store pointer to new variable
     1500 */
     1501static void run_var_new_tprimitive(run_t *run, tdata_primitive_t *tprimitive,
     1502    rdata_var_t **rvar)
     1503{
     1504        rdata_var_t *var;
     1505
     1506        (void) run;
     1507
     1508        /* Make compiler happy. */
     1509        var = NULL;
     1510
     1511        switch (tprimitive->tpc) {
     1512        case tpc_bool:
     1513                var = rdata_var_new(vc_bool);
     1514                var->u.bool_v = rdata_bool_new();
     1515                var->u.bool_v->value = b_false;
     1516                break;
     1517        case tpc_char:
     1518                var = rdata_var_new(vc_char);
     1519                var->u.char_v = rdata_char_new();
     1520                bigint_init(&var->u.char_v->value, 0);
     1521                break;
     1522        case tpc_int:
     1523                var = rdata_var_new(vc_int);
     1524                var->u.int_v = rdata_int_new();
     1525                bigint_init(&var->u.int_v->value, 0);
     1526                break;
     1527        case tpc_nil:
     1528                assert(b_false);
     1529        case tpc_string:
     1530                var = rdata_var_new(vc_string);
     1531                var->u.string_v = rdata_string_new();
     1532                var->u.string_v->value = "";
     1533                break;
     1534        case tpc_resource:
     1535                var = rdata_var_new(vc_resource);
     1536                var->u.resource_v = rdata_resource_new();
     1537                var->u.resource_v->data = NULL;
     1538                break;
     1539        }
     1540
     1541        *rvar = var;
     1542}
     1543
     1544/** Construct a new variable containing null reference.
     1545 *
     1546 * @param run           Runner object
     1547 * @param rvar          Place to store pointer to new variable
     1548 */
     1549static void run_var_new_null_ref(run_t *run, rdata_var_t **rvar)
     1550{
     1551        rdata_var_t *var;
     1552
     1553        (void) run;
     1554
     1555        /* Return null reference. */
     1556        var = rdata_var_new(vc_ref);
     1557        var->u.ref_v = rdata_ref_new();
     1558
     1559        *rvar = var;
     1560}
     1561
     1562/** Construct a new variable containing invalid delegate.
     1563 *
     1564 * @param run           Runner object
     1565 * @param rvar          Place to store pointer to new variable
     1566 */
     1567static void run_var_new_deleg(run_t *run, rdata_var_t **rvar)
     1568{
     1569        rdata_var_t *var;
     1570
     1571        (void) run;
     1572
     1573        /* Return null reference. */
     1574        var = rdata_var_new(vc_deleg);
     1575        var->u.deleg_v = rdata_deleg_new();
     1576
     1577        *rvar = var;
     1578}
     1579
     1580/** Construct a new thread activation record.
     1581 *
     1582 * @param run   Runner object
     1583 * @return      New thread AR.
     1584 */
    12781585run_thread_ar_t *run_thread_ar_new(void)
    12791586{
     
    12891596}
    12901597
     1598/** Construct a new procedure activation record.
     1599 *
     1600 * @param run   Runner object
     1601 * @return      New procedure AR.
     1602 */
    12911603run_proc_ar_t *run_proc_ar_new(void)
    12921604{
     
    13021614}
    13031615
     1616/** Construct a new block activation record.
     1617 *
     1618 * @param run   Runner object
     1619 * @return      New block AR.
     1620 */
    13041621run_block_ar_t *run_block_ar_new(void)
    13051622{
  • uspace/app/sbi/src/run.h

    r80badbe r883fedc  
    6868bool_t run_is_bo(run_t *run);
    6969
     70void run_var_new(run_t *run, tdata_item_t *ti, rdata_var_t **rvar);
     71
    7072run_thread_ar_t *run_thread_ar_new(void);
    7173run_proc_ar_t *run_proc_ar_new(void);
  • uspace/app/sbi/src/run_expr.c

    r80badbe r883fedc  
    2727 */
    2828
    29 /** @file Runner (executes the code). */
     29/** @file Run expressions. */
    3030
    3131#include <stdio.h>
     
    109109static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res);
    110110static void run_as(run_t *run, stree_as_t *as_op, rdata_item_t **res);
    111 
    112 /** Evaluate expression. */
     111static void run_box(run_t *run, stree_box_t *box, rdata_item_t **res);
     112
     113/** Evaluate expression.
     114 *
     115 * Run the expression @a expr and store pointer to the result in *(@a res).
     116 * If the expression has on value (assignment) then @c NULL is returned.
     117 * @c NULL is also returned if an error or exception occurs.
     118 *
     119 * @param run           Runner object
     120 * @param expr          Expression to run
     121 * @param res           Place to store result
     122 */
    113123void run_expr(run_t *run, stree_expr_t *expr, rdata_item_t **res)
    114124{
     
    151161                run_as(run, expr->u.as_op, res);
    152162                break;
     163        case ec_box:
     164                run_box(run, expr->u.box, res);
     165                break;
    153166        }
    154167
     
    160173}
    161174
    162 /** Evaluate name reference expression. */
     175/** Evaluate name reference expression.
     176 *
     177 * @param run           Runner object
     178 * @param nameref       Name reference
     179 * @param res           Place to store result
     180 */
    163181static void run_nameref(run_t *run, stree_nameref_t *nameref,
    164182    rdata_item_t **res)
     
    247265                assert(csi != NULL);
    248266
    249                 if (sym->outer_csi != csi) {
     267                if (symbol_search_csi(run->program, csi, nameref->name)
     268                    == NULL) {
    250269                        /* Function is not in the current object. */
    251270                        printf("Error: Cannot access non-static member "
     
    283302                assert(obj != NULL);
    284303
    285                 if (sym->outer_csi != csi) {
     304                if (symbol_search_csi(run->program, csi, nameref->name)
     305                    == NULL) {
    286306                        /* Variable is not in the current object. */
    287307                        printf("Error: Cannot access non-static member "
     
    316336}
    317337
    318 /** Evaluate literal. */
     338/** Evaluate literal.
     339 *
     340 * @param run           Runner object
     341 * @param literal       Literal
     342 * @param res           Place to store result
     343 */
    319344static void run_literal(run_t *run, stree_literal_t *literal,
    320345    rdata_item_t **res)
     
    342367}
    343368
    344 /** Evaluate Boolean literal. */
     369/** Evaluate Boolean literal.
     370 *
     371 * @param run           Runner object
     372 * @param lit_bool      Boolean literal
     373 * @param res           Place to store result
     374 */
    345375static void run_lit_bool(run_t *run, stree_lit_bool_t *lit_bool,
    346376    rdata_item_t **res)
     
    396426}
    397427
    398 /** Evaluate integer literal. */
     428/** Evaluate integer literal.
     429 *
     430 * @param run           Runner object
     431 * @param lit_int       Integer literal
     432 * @param res           Place to store result
     433 */
    399434static void run_lit_int(run_t *run, stree_lit_int_t *lit_int,
    400435    rdata_item_t **res)
     
    423458}
    424459
    425 /** Evaluate reference literal (@c nil). */
     460/** Evaluate reference literal (@c nil).
     461 *
     462 * @param run           Runner object
     463 * @param lit_ref       Reference literal
     464 * @param res           Place to store result
     465 */
    426466static void run_lit_ref(run_t *run, stree_lit_ref_t *lit_ref,
    427467    rdata_item_t **res)
     
    451491}
    452492
    453 /** Evaluate string literal. */
     493/** Evaluate string literal.
     494 *
     495 * @param run           Runner object
     496 * @param lit_string    String literal
     497 * @param res           Place to store result
     498 */
    454499static void run_lit_string(run_t *run, stree_lit_string_t *lit_string,
    455500    rdata_item_t **res)
     
    478523}
    479524
    480 /** Evaluate @c self reference. */
     525/** Evaluate @c self reference.
     526 *
     527 * @param run           Runner object
     528 * @param self_ref      Self reference
     529 * @param res           Place to store result
     530 */
    481531static void run_self_ref(run_t *run, stree_self_ref_t *self_ref,
    482532    rdata_item_t **res)
     
    494544}
    495545
    496 /** Evaluate binary operation. */
     546/** Evaluate binary operation.
     547 *
     548 * @param run           Runner object
     549 * @param binop         Binary operation
     550 * @param res           Place to store result
     551 */
    497552static void run_binop(run_t *run, stree_binop_t *binop, rdata_item_t **res)
    498553{
     
    574629}
    575630
    576 /** Evaluate binary operation on bool arguments. */
     631/** Evaluate binary operation on bool arguments.
     632 *
     633 * @param run           Runner object
     634 * @param binop         Binary operation
     635 * @param v1            Value of first argument
     636 * @param v2            Value of second argument
     637 * @param res           Place to store result
     638 */
    577639static void run_binop_bool(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    578640    rdata_value_t *v2, rdata_item_t **res)
     
    628690}
    629691
    630 /** Evaluate binary operation on char arguments. */
     692/** Evaluate binary operation on char arguments.
     693 *
     694 * @param run           Runner object
     695 * @param binop         Binary operation
     696 * @param v1            Value of first argument
     697 * @param v2            Value of second argument
     698 * @param res           Place to store result
     699*/
    631700static void run_binop_char(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    632701    rdata_value_t *v2, rdata_item_t **res)
     
    691760}
    692761
    693 /** Evaluate binary operation on int arguments. */
     762/** Evaluate binary operation on int arguments.
     763 *
     764 * @param run           Runner object
     765 * @param binop         Binary operation
     766 * @param v1            Value of first argument
     767 * @param v2            Value of second argument
     768 * @param res           Place to store result
     769*/
    694770static void run_binop_int(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    695771    rdata_value_t *v2, rdata_item_t **res)
     
    781857}
    782858
    783 /** Evaluate binary operation on string arguments. */
     859/** Evaluate binary operation on string arguments.
     860 *
     861 * @param run           Runner object
     862 * @param binop         Binary operation
     863 * @param v1            Value of first argument
     864 * @param v2            Value of second argument
     865 * @param res           Place to store result
     866 */
    784867static void run_binop_string(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    785868    rdata_value_t *v2, rdata_item_t **res)
     
    790873        rdata_string_t *string_v;
    791874
    792         char *s1, *s2;
     875        const char *s1, *s2;
    793876
    794877        (void) run;
     
    820903}
    821904
    822 /** Evaluate binary operation on ref arguments. */
     905/** Evaluate binary operation on ref arguments.
     906 *
     907 * @param run           Runner object
     908 * @param binop         Binary operation
     909 * @param v1            Value of first argument
     910 * @param v2            Value of second argument
     911 * @param res           Place to store result
     912 */
    823913static void run_binop_ref(run_t *run, stree_binop_t *binop, rdata_value_t *v1,
    824914    rdata_value_t *v2, rdata_item_t **res)
     
    862952
    863953
    864 /** Evaluate unary operation. */
     954/** Evaluate unary operation.
     955 *
     956 * @param run           Runner object
     957 * @param unop          Unary operation
     958 * @param res           Place to store result
     959 */
    865960static void run_unop(run_t *run, stree_unop_t *unop, rdata_item_t **res)
    866961{
     
    898993}
    899994
    900 /** Evaluate unary operation on int argument. */
     995/** Evaluate unary operation on int argument.
     996 *
     997 * @param run           Runner object
     998 * @param unop          Unary operation
     999 * @param val           Value of argument
     1000 * @param res           Place to store result
     1001 */
    9011002static void run_unop_int(run_t *run, stree_unop_t *unop, rdata_value_t *val,
    9021003    rdata_item_t **res)
     
    9321033
    9331034
    934 /** Evaluate @c new operation. */
     1035/** Evaluate @c new operation.
     1036 *
     1037 * Evaluates operation per the @c new operator that creates a new
     1038 * instance of some type.
     1039 *
     1040 * @param run           Runner object
     1041 * @param unop          Unary operation
     1042 * @param res           Place to store result
     1043 */
    9351044static void run_new(run_t *run, stree_new_t *new_op, rdata_item_t **res)
    9361045{
     
    9581067}
    9591068
    960 /** Create new array. */
     1069/** Create new array.
     1070 *
     1071 * @param run           Runner object
     1072 * @param new_op        New operation
     1073 * @param titem         Type of new var node (tic_tarray)
     1074 * @param res           Place to store result
     1075 */
    9611076static void run_new_array(run_t *run, stree_new_t *new_op,
    9621077    tdata_item_t *titem, rdata_item_t **res)
     
    10461161        /* Create member variables */
    10471162        for (i = 0; i < length; ++i) {
    1048                 /* XXX Depends on member variable type. */
    1049                 elem_var = rdata_var_new(vc_int);
    1050                 elem_var->u.int_v = rdata_int_new();
    1051                 bigint_init(&elem_var->u.int_v->value, 0);
     1163                /* Create and initialize element. */
     1164                run_var_new(run, tarray->base_ti, &elem_var);
    10521165
    10531166                array->element[i] = elem_var;
     
    10621175}
    10631176
    1064 /** Create new object. */
     1177/** Create new object.
     1178 *
     1179 * @param run           Runner object
     1180 * @param new_op        New operation
     1181 * @param titem         Type of new var node (tic_tobject)
     1182 * @param res           Place to store result
     1183 */
    10651184static void run_new_object(run_t *run, stree_new_t *new_op,
    10661185    tdata_item_t *titem, rdata_item_t **res)
     
    10811200}
    10821201
    1083 /** Evaluate member acccess. */
     1202/** Evaluate member acccess.
     1203 *
     1204 * Evaluate operation per the member access ('.') operator.
     1205 *
     1206 * @param run           Runner object
     1207 * @param access        Access operation
     1208 * @param res           Place to store result
     1209 */
    10841210static void run_access(run_t *run, stree_access_t *access, rdata_item_t **res)
    10851211{
     
    11031229}
    11041230
    1105 /** Evaluate member acccess (with base already evaluated). */
     1231/** Evaluate member acccess (with base already evaluated).
     1232 *
     1233 * @param run           Runner object
     1234 * @param access        Access operation
     1235 * @param arg           Evaluated base expression
     1236 * @param res           Place to store result
     1237 */
    11061238static void run_access_item(run_t *run, stree_access_t *access,
    11071239    rdata_item_t *arg, rdata_item_t **res)
     
    11311263}
    11321264
    1133 /** Evaluate reference acccess. */
     1265/** Evaluate reference acccess.
     1266 *
     1267 * @param run           Runner object
     1268 * @param access        Access operation
     1269 * @param arg           Evaluated base expression
     1270 * @param res           Place to store result
     1271 */
    11341272static void run_access_ref(run_t *run, stree_access_t *access,
    11351273    rdata_item_t *arg, rdata_item_t **res)
     
    11491287}
    11501288
    1151 /** Evaluate delegate-member acccess. */
     1289/** Evaluate delegate-member acccess.
     1290 *
     1291 * @param run           Runner object
     1292 * @param access        Access operation
     1293 * @param arg           Evaluated base expression
     1294 * @param res           Place to store result
     1295 */
    11521296static void run_access_deleg(run_t *run, stree_access_t *access,
    11531297    rdata_item_t *arg, rdata_item_t **res)
     
    11921336}
    11931337
    1194 /** Evaluate object member acccess. */
     1338/** Evaluate object member acccess.
     1339 *
     1340 * @param run           Runner object
     1341 * @param access        Access operation
     1342 * @param arg           Evaluated base expression
     1343 * @param res           Place to store result
     1344 */
    11951345static void run_access_object(run_t *run, stree_access_t *access,
    11961346    rdata_item_t *arg, rdata_item_t **res)
     
    12361386#endif
    12371387
     1388        /* Make compiler happy. */
     1389        ritem = NULL;
     1390
    12381391        switch (member->sc) {
    12391392        case sc_csi:
    12401393                printf("Error: Accessing object member which is nested CSI.\n");
    12411394                exit(1);
     1395        case sc_deleg:
     1396                printf("Error: Accessing object member which is a delegate.\n");
     1397                exit(1);
    12421398        case sc_fun:
    1243                 /* Construct delegate. */
     1399                /* Construct anonymous delegate. */
    12441400                ritem = rdata_item_new(ic_value);
    12451401                value = rdata_value_new();
     
    12811437                addr_prop->u.named->prop_d = deleg_p;
    12821438                break;
    1283         default:
    1284                 ritem = NULL;
    12851439        }
    12861440
     
    12881442}
    12891443
    1290 /** Call a function. */
     1444/** Call a function.
     1445 *
     1446 * Call a function and return the result in @a res.
     1447 *
     1448 * @param run           Runner object
     1449 * @param call          Call operation
     1450 * @param res           Place to store result
     1451 */
    12911452static void run_call(run_t *run, stree_call_t *call, rdata_item_t **res)
    12921453{
    1293         rdata_item_t *rfun;
     1454        rdata_item_t *rdeleg, *rdeleg_vi;
    12941455        rdata_deleg_t *deleg_v;
    12951456        list_t arg_vals;
     
    13041465        printf("Run call operation.\n");
    13051466#endif
    1306         run_expr(run, call->fun, &rfun);
     1467        run_expr(run, call->fun, &rdeleg);
    13071468        if (run_is_bo(run)) {
    13081469                *res = NULL;
     
    13151476        }
    13161477
    1317         if (rfun->ic != ic_value || rfun->u.value->var->vc != vc_deleg) {
    1318                 printf("Unimplemented: Call expression of this type.\n");
     1478        run_cvt_value_item(run, rdeleg, &rdeleg_vi);
     1479        assert(rdeleg_vi->ic == ic_value);
     1480
     1481        if (rdeleg_vi->u.value->var->vc != vc_deleg) {
     1482                printf("Unimplemented: Call expression of this type (");
     1483                rdata_item_print(rdeleg_vi);
     1484                printf(").\n");
    13191485                exit(1);
    13201486        }
    13211487
    1322         deleg_v = rfun->u.value->var->u.deleg_v;
     1488        deleg_v = rdeleg_vi->u.value->var->u.deleg_v;
    13231489
    13241490        if (deleg_v->sym->sc != sc_fun) {
     
    13671533}
    13681534
    1369 /** Run index operation. */
     1535/** Run index operation.
     1536 *
     1537 * Evaluate operation per the indexing ('[', ']') operator.
     1538 *
     1539 * @param run           Runner object
     1540 * @param index         Index operation
     1541 * @param res           Place to store result
     1542 */
    13701543static void run_index(run_t *run, stree_index_t *index, rdata_item_t **res)
    13711544{
     
    14331606}
    14341607
    1435 /** Run index operation on array. */
     1608/** Run index operation on array.
     1609 *
     1610 * @param run           Runner object
     1611 * @param index         Index operation
     1612 * @param base          Evaluated base expression
     1613 * @param args          Evaluated indices (list of rdata_item_t)
     1614 * @param res           Place to store result
     1615 */
    14361616static void run_index_array(run_t *run, stree_index_t *index,
    14371617    rdata_item_t *base, list_t *args, rdata_item_t **res)
     
    15251705}
    15261706
    1527 /** Index an object (via its indexer). */
     1707/** Index an object (via its indexer).
     1708 *
     1709 * @param run           Runner object
     1710 * @param index         Index operation
     1711 * @param base          Evaluated base expression
     1712 * @param args          Evaluated indices (list of rdata_item_t)
     1713 * @param res           Place to store result
     1714 */
    15281715static void run_index_object(run_t *run, stree_index_t *index,
    15291716    rdata_item_t *base, list_t *args, rdata_item_t **res)
     
    15971784}
    15981785
    1599 /** Run index operation on string. */
     1786/** Run index operation on string.
     1787 *
     1788 * @param run           Runner object
     1789 * @param index         Index operation
     1790 * @param base          Evaluated base expression
     1791 * @param args          Evaluated indices (list of rdata_item_t)
     1792 * @param res           Place to store result
     1793 */
    16001794static void run_index_string(run_t *run, stree_index_t *index,
    16011795    rdata_item_t *base, list_t *args, rdata_item_t **res)
     
    16901884}
    16911885
    1692 /** Execute assignment. */
     1886/** Run assignment.
     1887 *
     1888 * Executes an assignment. @c NULL is always stored to @a res because
     1889 * an assignment does not have a value.
     1890 *
     1891 * @param run           Runner object
     1892 * @param assign        Assignment expression
     1893 * @param res           Place to store result
     1894*/
    16931895static void run_assign(run_t *run, stree_assign_t *assign, rdata_item_t **res)
    16941896{
     
    17271929}
    17281930
    1729 /** Execute @c as conversion. */
     1931/** Execute @c as conversion.
     1932 *
     1933 * @param run           Runner object
     1934 * @param as_op         @c as conversion expression
     1935 * @param res           Place to store result
     1936 */
    17301937static void run_as(run_t *run, stree_as_t *as_op, rdata_item_t **res)
    17311938{
     
    17942001}
    17952002
    1796 /** Create new CSI instance. */
     2003/** Execute boxing operation.
     2004 *
     2005 * XXX We can scrap this special operation once we have constructors.
     2006 *
     2007 * @param run           Runner object
     2008 * @param box           Boxing operation
     2009 * @param res           Place to store result
     2010 */
     2011static void run_box(run_t *run, stree_box_t *box, rdata_item_t **res)
     2012{
     2013        rdata_item_t *rarg_i;
     2014        rdata_item_t *rarg_vi;
     2015
     2016        stree_symbol_t *csi_sym;
     2017        stree_csi_t *csi;
     2018        builtin_t *bi;
     2019        rdata_var_t *var;
     2020        rdata_object_t *object;
     2021
     2022        sid_t mbr_name_sid;
     2023        rdata_var_t *mbr_var;
     2024
     2025#ifdef DEBUG_RUN_TRACE
     2026        printf("Run boxing operation.\n");
     2027#endif
     2028        run_expr(run, box->arg, &rarg_i);
     2029        if (run_is_bo(run)) {
     2030                *res = NULL;
     2031                return;
     2032        }
     2033
     2034        run_cvt_value_item(run, rarg_i, &rarg_vi);
     2035        assert(rarg_vi->ic == ic_value);
     2036
     2037        bi = run->program->builtin;
     2038
     2039        /* Just to keep the compiler happy. */
     2040        csi_sym = NULL;
     2041
     2042        switch (rarg_vi->u.value->var->vc) {
     2043        case vc_bool: csi_sym = bi->boxed_bool; break;
     2044        case vc_char: csi_sym = bi->boxed_char; break;
     2045        case vc_int: csi_sym = bi->boxed_int; break;
     2046        case vc_string: csi_sym = bi->boxed_string; break;
     2047
     2048        case vc_ref:
     2049        case vc_deleg:
     2050        case vc_array:
     2051        case vc_object:
     2052        case vc_resource:
     2053                assert(b_false);
     2054        }
     2055
     2056        csi = symbol_to_csi(csi_sym);
     2057        assert(csi != NULL);
     2058
     2059        /* Construct object of the relevant boxed type. */
     2060        run_new_csi_inst(run, csi, res);
     2061
     2062        /* Set the 'Value' field */
     2063
     2064        assert((*res)->ic == ic_value);
     2065        assert((*res)->u.value->var->vc == vc_ref);
     2066        var = (*res)->u.value->var->u.ref_v->vref;
     2067        assert(var->vc == vc_object);
     2068        object = var->u.object_v;
     2069
     2070        mbr_name_sid = strtab_get_sid("Value");
     2071        mbr_var = intmap_get(&object->fields, mbr_name_sid);
     2072        assert(mbr_var != NULL);
     2073
     2074        rdata_var_write(mbr_var, rarg_vi->u.value);
     2075}
     2076
     2077/** Create new CSI instance.
     2078 *
     2079 * Create a new object, instance of @a csi.
     2080 * XXX This does not work with generics as @a csi cannot specify a generic
     2081 * type.
     2082 *
     2083 * Initialize the fields with default values of their types, but do not
     2084 * run any constructor.
     2085 *
     2086 * @param run           Runner object
     2087 * @param as_op         @c as conversion expression
     2088 * @param res           Place to store result
     2089 */
    17972090void run_new_csi_inst(run_t *run, stree_csi_t *csi, rdata_item_t **res)
    17982091{
     
    18042097
    18052098        rdata_var_t *mbr_var;
    1806 
    18072099        list_node_t *node;
     2100        tdata_item_t *field_ti;
    18082101
    18092102        csi_sym = csi_to_symbol(csi);
     
    18242117
    18252118        /* Create object fields. */
    1826         node = list_first(&csi->members);
    1827         while (node != NULL) {
    1828                 csimbr = list_node_data(node, stree_csimbr_t *);
    1829                 if (csimbr->cc == csimbr_var) {
    1830                         /* XXX Depends on member variable type. */
    1831                         mbr_var = rdata_var_new(vc_int);
    1832                         mbr_var->u.int_v = rdata_int_new();
    1833                         bigint_init(&mbr_var->u.int_v->value, 0);
    1834 
    1835                         intmap_set(&obj->fields, csimbr->u.var->name->sid,
    1836                             mbr_var);
     2119        while (csi != NULL) {
     2120                node = list_first(&csi->members);
     2121                while (node != NULL) {
     2122                        csimbr = list_node_data(node, stree_csimbr_t *);
     2123                        if (csimbr->cc == csimbr_var) {
     2124                                /* Compute field type. XXX Memoize. */
     2125                                run_texpr(run->program, csi,
     2126                                    csimbr->u.var->type,
     2127                                    &field_ti);
     2128
     2129                                /* Create and initialize field. */
     2130                                run_var_new(run, field_ti, &mbr_var);
     2131
     2132                                /* Add to field map. */
     2133                                intmap_set(&obj->fields,
     2134                                    csimbr->u.var->name->sid,
     2135                                    mbr_var);
     2136                        }
     2137
     2138                        node = list_next(&csi->members, node);
    18372139                }
    18382140
    1839                 node = list_next(&csi->members, node);
     2141                /* Continue with base CSI */
     2142                csi = csi->base_csi;
    18402143        }
    18412144
     
    18462149/** Return boolean value of an item.
    18472150 *
    1848  * Tries to interpret @a item as a boolean value. If it is not a boolean
    1849  * value, this generates an error.
     2151 * Try to interpret @a item as a boolean value. If it is not a boolean
     2152 * value, generate an error.
     2153 *
     2154 * @param run           Runner object
     2155 * @param item          Input item
     2156 * @return              Resulting boolean value
    18502157 */
    18512158bool_t run_item_boolean_value(run_t *run, rdata_item_t *item)
  • uspace/app/sbi/src/run_texpr.c

    r80badbe r883fedc  
    2727 */
    2828
    29 /** @file Evaluates type expressions. */
     29/** @file Evaluate type expressions. */
    3030
    3131#include <assert.h>
    3232#include <stdlib.h>
     33#include "debug.h"
    3334#include "list.h"
    3435#include "mytypes.h"
     36#include "stree.h"
    3537#include "strtab.h"
    3638#include "symbol.h"
     
    5052    stree_tapply_t *tapply, tdata_item_t **res);
    5153
     54/** Evaluate type expression.
     55 *
     56 * Evaluate type expression (this produces a type item). If a type error
     57 * occurs, the resulting type item is of class @c tic_ignore.
     58 *
     59 * @param prog          Program
     60 * @param ctx           Current CSI (context)
     61 * @param texpr         Type expression to evaluate
     62 * @param res           Place to store type result
     63 */
    5264void run_texpr(stree_program_t *prog, stree_csi_t *ctx, stree_texpr_t *texpr,
    5365    tdata_item_t **res)
     
    7284}
    7385
     86/** Evaluate type access expression.
     87 *
     88 * Evaluate operation per the type access ('.') operator.
     89 *
     90 * @param prog          Program
     91 * @param ctx           Current CSI (context)
     92 * @param taccess       Type access expression to evaluate
     93 * @param res           Place to store type result
     94 */
    7495static void run_taccess(stree_program_t *prog, stree_csi_t *ctx,
    7596    stree_taccess_t *taccess, tdata_item_t **res)
     
    79100        tdata_item_t *titem;
    80101        tdata_object_t *tobject;
     102        tdata_deleg_t *tdeleg;
    81103        stree_csi_t *base_csi;
    82104
     
    111133        }
    112134
    113         if (sym->sc != sc_csi) {
     135        switch (sym->sc) {
     136        case sc_csi:
     137                /* Construct type item. */
     138                titem = tdata_item_new(tic_tobject);
     139                tobject = tdata_object_new();
     140                titem->u.tobject = tobject;
     141
     142                tobject->static_ref = b_false;
     143                tobject->csi = sym->u.csi;
     144                list_init(&tobject->targs); /* XXX */
     145                break;
     146        case sc_deleg:
     147                /* Construct type item. */
     148                titem = tdata_item_new(tic_tdeleg);
     149                tdeleg = tdata_deleg_new();
     150                titem->u.tdeleg = tdeleg;
     151
     152                tdeleg->deleg = sym->u.deleg;
     153                break;
     154        case sc_fun:
     155        case sc_var:
     156        case sc_prop:
    114157                printf("Error: Symbol '");
    115158                symbol_print_fqn(sym);
    116                 printf("' is not a CSI.\n");
    117                 *res = tdata_item_new(tic_ignore);
    118                 return;
    119         }
    120 
    121         /* Construct type item. */
    122         titem = tdata_item_new(tic_tobject);
    123         tobject = tdata_object_new();
    124         titem->u.tobject = tobject;
    125 
    126         tobject->static_ref = b_false;
    127         tobject->csi = sym->u.csi;
     159                printf("' is not a type.\n");
     160                titem = tdata_item_new(tic_ignore);
     161                break;
     162        }
    128163
    129164        *res = titem;
    130165}
    131166
     167/** Evaluate type indexing expression.
     168 *
     169 * Evaluate operation per the type indexing ('[', ']') operator.
     170 * A type indexing operation may have extents specified or only rank
     171 * specified.
     172 *
     173 * @param prog          Program
     174 * @param ctx           Current CSI (context)
     175 * @param tindex        Type indexing expression to evaluate
     176 * @param res           Place to store type result
     177 */
    132178static void run_tindex(stree_program_t *prog, stree_csi_t *ctx,
    133179    stree_tindex_t *tindex, tdata_item_t **res)
     
    171217}
    172218
     219/** Evaluate type literal expression.
     220 *
     221 * @param prog          Program
     222 * @param ctx           Current CSI (context)
     223 * @param tliteral      Type literal
     224 * @param res           Place to store type result
     225 */
    173226static void run_tliteral(stree_program_t *prog, stree_csi_t *ctx,
    174227    stree_tliteral_t *tliteral, tdata_item_t **res)
     
    207260        tdata_item_t *titem;
    208261        tdata_object_t *tobject;
     262        stree_targ_t *targ;
     263        tdata_vref_t *tvref;
     264        stree_deleg_t *deleg;
     265        tdata_deleg_t *tdeleg;
    209266
    210267#ifdef DEBUG_RUN_TRACE
    211268        printf("Evaluating type name reference.\n");
    212 #endif
     269        printf("'%s'\n", strtab_get_str(tnameref->name->sid));
     270#endif
     271        /* In interactive mode we are not in a class */
     272        if (ctx != NULL) {
     273                /* Look for type argument */
     274                targ = stree_csi_find_targ(ctx, tnameref->name);
     275
     276                if (targ != NULL) {
     277                        /* Found type argument */
     278#ifdef DEBUG_RUN_TRACE
     279                        printf("Found type argument '%s'.\n",
     280                            strtab_get_str(tnameref->name->sid));
     281#endif
     282                        titem = tdata_item_new(tic_tvref);
     283                        tvref = tdata_vref_new();
     284                        titem->u.tvref = tvref;
     285                        tvref->targ = targ;
     286
     287                        *res = titem;
     288                        return;
     289                }
     290        }
     291
     292        /* Look for symbol */
    213293        sym = symbol_lookup_in_csi(prog, ctx, tnameref->name);
    214294        if (sym == NULL) {
     
    219299        }
    220300
    221         if (sym->sc != sc_csi) {
     301        switch (sym->sc) {
     302        case sc_csi:
     303                /* Construct type item. */
     304                titem = tdata_item_new(tic_tobject);
     305                tobject = tdata_object_new();
     306                titem->u.tobject = tobject;
     307
     308                tobject->static_ref = b_false;
     309                tobject->csi = sym->u.csi;
     310                list_init(&tobject->targs); /* XXX */
     311                break;
     312        case sc_deleg:
     313                /* Fetch stored delegate type. */
     314                deleg = symbol_to_deleg(sym);
     315                assert(deleg != NULL);
     316                if (deleg->titem == NULL) {
     317                        /*
     318                         * Prepare a partial delegate which will be completed
     319                         * later.
     320                         */
     321                        titem = tdata_item_new(tic_tdeleg);
     322                        tdeleg = tdata_deleg_new();
     323                        titem->u.tdeleg = tdeleg;
     324                        tdeleg->deleg = deleg;
     325                        tdeleg->tsig = NULL;
     326
     327                        deleg->titem = titem;
     328                } else {
     329                        titem = deleg->titem;
     330                }
     331                break;
     332        case sc_fun:
     333        case sc_var:
     334        case sc_prop:
    222335                printf("Error: Symbol '");
    223336                symbol_print_fqn(sym);
    224                 printf("' is not a CSI.\n");
    225                 *res = tdata_item_new(tic_ignore);
    226                 return;
    227         }
    228 
     337                printf("' is not a type.\n");
     338                titem = tdata_item_new(tic_ignore);
     339                break;
     340        }
     341
     342        *res = titem;
     343}
     344
     345/** Evaluate type application expression.
     346 *
     347 * In a type application expression type arguments are applied to a generic
     348 * CSI.
     349 *
     350 * @param prog          Program
     351 * @param ctx           Current CSI (context)
     352 * @param tapply        Type application expression
     353 * @param res           Place to store type result
     354 */
     355static void run_tapply(stree_program_t *prog, stree_csi_t *ctx,
     356    stree_tapply_t *tapply, tdata_item_t **res)
     357{
     358        tdata_item_t *base_ti;
     359        tdata_item_t *arg_ti;
     360        tdata_item_t *titem;
     361        tdata_object_t *tobject;
     362
     363        list_node_t *arg_n;
     364        stree_texpr_t *arg;
     365
     366        list_node_t *farg_n;
     367        stree_targ_t *farg;
     368
     369#ifdef DEBUG_RUN_TRACE
     370        printf("Evaluating type apply operation.\n");
     371#endif
    229372        /* Construct type item. */
    230373        titem = tdata_item_new(tic_tobject);
     
    232375        titem->u.tobject = tobject;
    233376
    234         tobject->static_ref = b_false;
    235         tobject->csi = sym->u.csi;
    236 
    237         *res = titem;
    238 }
    239 
    240 static void run_tapply(stree_program_t *prog, stree_csi_t *ctx,
    241     stree_tapply_t *tapply, tdata_item_t **res)
    242 {
    243         tdata_item_t *base_ti;
    244         tdata_item_t *arg_ti;
    245         tdata_item_t *titem;
    246         tdata_object_t *tobject;
    247 
    248         list_node_t *arg_n;
    249         stree_texpr_t *arg;
    250 
    251 #ifdef DEBUG_RUN_TRACE
    252         printf("Evaluating type apply operation.\n");
    253 #endif
    254         /* Construct type item. */
    255         titem = tdata_item_new(tic_tobject);
    256         tobject = tdata_object_new();
    257         titem->u.tobject = tobject;
    258 
    259377        /* Evaluate base (generic) type. */
    260378        run_texpr(prog, ctx, tapply->gtype, &base_ti);
     
    272390
    273391        /* Evaluate type arguments. */
     392        farg_n = list_first(&tobject->csi->targ);
    274393        arg_n = list_first(&tapply->targs);
    275         while (arg_n != NULL) {
     394        while (farg_n != NULL && arg_n != NULL) {
     395                farg = list_node_data(farg_n, stree_targ_t *);
    276396                arg = list_node_data(arg_n, stree_texpr_t *);
     397
    277398                run_texpr(prog, ctx, arg, &arg_ti);
    278399
     
    284405                list_append(&tobject->targs, arg_ti);
    285406
     407                farg_n = list_next(&tobject->csi->targ, farg_n);
    286408                arg_n = list_next(&tapply->targs, arg_n);
    287409        }
    288410
     411        if (farg_n != NULL || arg_n != NULL) {
     412                printf("Error: Incorrect number of type arguments.\n");
     413                *res = tdata_item_new(tic_ignore);
     414                return;
     415        }
     416
    289417        *res = titem;
    290418}
  • uspace/app/sbi/src/stree.c

    r80badbe r883fedc  
    3737#include "stree.h"
    3838
     39/** Allocate new module.
     40 *
     41 * @return      New module
     42 */
    3943stree_module_t *stree_module_new(void)
    4044{
     
    5155}
    5256
     57/** Allocate new module member.
     58 *
     59 * @param mc    Module member class
     60 * @return      New module member
     61 */
    5362stree_modm_t *stree_modm_new(modm_class_t mc)
    5463{
     
    6574}
    6675
     76/** Allocate new CSI.
     77 *
     78 * @param cc    CSI class
     79 * @return      New CSI
     80 */
    6781stree_csi_t *stree_csi_new(csi_class_t cc)
    6882{
     
    8397}
    8498
     99/** Allocate new CSI member.
     100 *
     101 * @param cc    CSI member class
     102 * @return      New CSI member
     103 */
    85104stree_csimbr_t *stree_csimbr_new(csimbr_class_t cc)
    86105{
     
    97116}
    98117
     118/** Allocate new member delegate.
     119 *
     120 * @return      New member delegate
     121 */
     122stree_deleg_t *stree_deleg_new(void)
     123{
     124        stree_deleg_t *deleg;
     125
     126        deleg = calloc(1, sizeof(stree_deleg_t));
     127        if (deleg == NULL) {
     128                printf("Memory allocation failed.\n");
     129                exit(1);
     130        }
     131
     132        return deleg;
     133}
     134
     135/** Allocate new member function.
     136 *
     137 * @return      New member function
     138 */
    99139stree_fun_t *stree_fun_new(void)
    100140{
     
    110150}
    111151
     152/** Allocate new member variable.
     153 *
     154 * @return      New member variable
     155 */
    112156stree_var_t *stree_var_new(void)
    113157{
     
    123167}
    124168
     169/** Allocate new property.
     170 *
     171 * @return      New property
     172 */
    125173stree_prop_t *stree_prop_new(void)
    126174{
     
    136184}
    137185
     186/** Allocate new type argument.
     187 *
     188 * @return      New type argument
     189 */
     190stree_targ_t *stree_targ_new(void)
     191{
     192        stree_targ_t *targ;
     193
     194        targ = calloc(1, sizeof(stree_targ_t));
     195        if (targ == NULL) {
     196                printf("Memory allocation failed.\n");
     197                exit(1);
     198        }
     199
     200        return targ;
     201}
     202
     203/** Allocate new symbol attribute.
     204 *
     205 * @param sac   Symbol attribute class
     206 * @return      New symbol attribute
     207 */
    138208stree_symbol_attr_t *stree_symbol_attr_new(symbol_attr_class_t sac)
    139209{
     
    150220}
    151221
     222/** Allocate new procedure.
     223 *
     224 * @return      New procedure
     225 */
    152226stree_proc_t *stree_proc_new(void)
    153227{
     
    163237}
    164238
     239/** Allocate new procedure argument.
     240 *
     241 * @return      New procedure argument
     242 */
    165243stree_proc_arg_t *stree_proc_arg_new(void)
    166244{
     
    176254}
    177255
     256/** Allocate new function signature.
     257 *
     258 * @return      New procedure argument
     259 */
     260stree_fun_sig_t *stree_fun_sig_new(void)
     261{
     262        stree_fun_sig_t *fun_sig;
     263
     264        fun_sig = calloc(1, sizeof(stree_fun_sig_t));
     265        if (fun_sig == NULL) {
     266                printf("Memory allocation failed.\n");
     267                exit(1);
     268        }
     269
     270        return fun_sig;
     271}
     272
     273/** Allocate new procedure argument attribute.
     274 *
     275 * @param       Argument attribute class
     276 * @return      New procedure argument attribute
     277 */
    178278stree_arg_attr_t *stree_arg_attr_new(arg_attr_class_t aac)
    179279{
     
    190290}
    191291
     292/** Allocate new statement.
     293 *
     294 * @param sc    Statement class
     295 * @return      New statement
     296 */
    192297stree_stat_t *stree_stat_new(stat_class_t sc)
    193298{
     
    204309}
    205310
     311/** Allocate new local variable declaration.
     312 *
     313 * @return      New local variable declaration
     314 */
    206315stree_vdecl_t *stree_vdecl_new(void)
    207316{
     
    217326}
    218327
     328/** Allocate new @c if statement.
     329 *
     330 * @return      New @c if statement
     331 */
    219332stree_if_t *stree_if_new(void)
    220333{
     
    230343}
    231344
     345/** Allocate new @c while statement.
     346 *
     347 * @return      New @c while statement
     348 */
    232349stree_while_t *stree_while_new(void)
    233350{
     
    243360}
    244361
     362/** Allocate new @c for statement.
     363 *
     364 * @return      New @c for statement
     365 */
    245366stree_for_t *stree_for_new(void)
    246367{
     
    256377}
    257378
     379/** Allocate new @c raise statement.
     380 *
     381 * @return      New @c raise statement
     382 */
    258383stree_raise_t *stree_raise_new(void)
    259384{
     
    269394}
    270395
     396/** Allocate new @c return statement.
     397 *
     398 * @return      New @c return statement
     399 */
    271400stree_return_t *stree_return_new(void)
    272401{
     
    282411}
    283412
     413/** Allocate new with-except-finally statement.
     414 *
     415 * @return      New with-except-finally statement.
     416 */
    284417stree_wef_t *stree_wef_new(void)
    285418{
     
    295428}
    296429
     430/** Allocate new expression statement.
     431 *
     432 * @return      New expression statement
     433 */
    297434stree_exps_t *stree_exps_new(void)
    298435{
     
    308445}
    309446
     447/** Allocate new @c except clause.
     448 *
     449 * @return      New @c except clause
     450 */
    310451stree_except_t *stree_except_new(void)
    311452{
     
    321462}
    322463
     464/** Allocate new statement block.
     465 *
     466 * @return      New statement block
     467 */
    323468stree_block_t *stree_block_new(void)
    324469{
     
    334479}
    335480
     481/** Allocate new expression.
     482 *
     483 * @param ec    Expression class
     484 * @return      New expression
     485 */
    336486stree_expr_t *stree_expr_new(expr_class_t ec)
    337487{
     
    348498}
    349499
     500/** Allocate new assignment.
     501 *
     502 * @param ac    Assignment class
     503 * @return      New assignment
     504 */
    350505stree_assign_t *stree_assign_new(assign_class_t ac)
    351506{
     
    362517}
    363518
     519/** Allocate new binary operation.
     520 *
     521 * @return      New binary operation
     522 */
    364523stree_binop_t *stree_binop_new(binop_class_t bc)
    365524{
     
    376535}
    377536
     537/** Allocate new unary operation.
     538 *
     539 * @param uc    Unary operation class
     540 * @return      New unary operation
     541 */
    378542stree_unop_t *stree_unop_new(unop_class_t uc)
    379543{
     
    390554}
    391555
     556/** Allocate new @c new operation.
     557 *
     558 * @return      New @c new operation
     559 */
    392560stree_new_t *stree_new_new(void)
    393561{
     
    403571}
    404572
     573/** Allocate new .
     574 *
     575 * @return      New
     576 */
    405577stree_access_t *stree_access_new(void)
    406578{
     
    416588}
    417589
     590/** Allocate new function call operation.
     591 *
     592 * @return      New function call operation
     593 */
    418594stree_call_t *stree_call_new(void)
    419595{
     
    429605}
    430606
     607/** Allocate new indexing operation.
     608 *
     609 * @return      New indexing operation
     610 */
    431611stree_index_t *stree_index_new(void)
    432612{
     
    442622}
    443623
     624/** Allocate new as conversion.
     625 *
     626 * @return      New as conversion
     627 */
    444628stree_as_t *stree_as_new(void)
    445629{
     
    455639}
    456640
     641/** Allocate new boxing operation.
     642 *
     643 * @return      New boxing operation
     644 */
     645stree_box_t *stree_box_new(void)
     646{
     647        stree_box_t *box_expr;
     648
     649        box_expr = calloc(1, sizeof(stree_box_t));
     650        if (box_expr == NULL) {
     651                printf("Memory allocation failed.\n");
     652                exit(1);
     653        }
     654
     655        return box_expr;
     656}
     657
     658/** Allocate new name reference operation.
     659 *
     660 * @return      New name reference operation
     661 */
    457662stree_nameref_t *stree_nameref_new(void)
    458663{
     
    468673}
    469674
     675/** Allocate new identifier.
     676 *
     677 * @return      New identifier
     678 */
    470679stree_ident_t *stree_ident_new(void)
    471680{
     
    481690}
    482691
     692/** Allocate new literal.
     693 *
     694 * @param ltc   Literal class
     695 * @return      New literal
     696 */
    483697stree_literal_t *stree_literal_new(literal_class_t ltc)
    484698{
     
    495709}
    496710
     711/** Allocate new @c self reference.
     712 *
     713 * @return      New @c self reference
     714 */
    497715stree_self_ref_t *stree_self_ref_new(void)
    498716{
     
    508726}
    509727
     728/** Allocate new type expression
     729 *
     730 * @return      New type expression
     731 */
    510732stree_texpr_t *stree_texpr_new(texpr_class_t tc)
    511733{
     
    522744}
    523745
     746/** Allocate new type access operation.
     747 *
     748 * @return      New type access operation
     749 */
    524750stree_taccess_t *stree_taccess_new(void)
    525751{
     
    535761}
    536762
     763/** Allocate new type application operation.
     764 *
     765 * @return      New type application operation
     766 */
    537767stree_tapply_t *stree_tapply_new(void)
    538768{
     
    548778}
    549779
     780/** Allocate new type indexing operation.
     781 *
     782 * @return      New type indexing operation
     783 */
    550784stree_tindex_t *stree_tindex_new(void)
    551785{
     
    561795}
    562796
     797/** Allocate new type literal.
     798 *
     799 * @return      New type literal
     800 */
    563801stree_tliteral_t *stree_tliteral_new(tliteral_class_t tlc)
    564802{
     
    575813}
    576814
     815/** Allocate new type name reference.
     816 *
     817 * @return      New type name reference
     818 */
    577819stree_tnameref_t *stree_tnameref_new(void)
    578820{
     
    588830}
    589831
     832/** Allocate new symbol.
     833 *
     834 * @return      New symbol
     835 */
    590836stree_symbol_t *stree_symbol_new(symbol_class_t sc)
    591837{
     
    602848}
    603849
     850/** Allocate new program.
     851 *
     852 * @return      New program
     853 */
    604854stree_program_t *stree_program_new(void)
    605855{
     
    615865}
    616866
    617 /** Determine if @a symbol has attribute of class @a sac. */
     867/** Determine if @a symbol has attribute of class @a sac.
     868 *
     869 * @param symbol        Symbol
     870 * @param sac           Symbol attribute class
     871 * @return              @c b_true if yes, @c b_false if no.
     872 */
    618873bool_t stree_symbol_has_attr(stree_symbol_t *symbol, symbol_attr_class_t sac)
    619874{
     
    633888}
    634889
    635 /** Determine if argument @a arg has attribute of class @a aac. */
     890/** Determine if argument @a arg has attribute of class @a aac.
     891 *
     892 * @param arg           Formal procedure argument
     893 * @param aac           Argument attribute class
     894 * @return              @c b_true if yes, @c b_false if no.
     895 */
    636896bool_t stree_arg_has_attr(stree_proc_arg_t *arg, arg_attr_class_t aac)
    637897{
     
    653913/** Determine wheter @a a is derived (transitively) from @a b.
    654914 *
     915 * XXX This does not work right with generics.
     916 *
    655917 * @param a     Derived CSI.
    656918 * @param b     Base CSI.
     
    673935        return b_false;
    674936}
     937
     938/** Search for CSI type argument of the given name.
     939 *
     940 * @param csi           CSI to look in.
     941 * @param ident         Identifier of the type argument.
     942 * @return              Type argument definition or @c NULL if not found.
     943 */
     944stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident)
     945{
     946        list_node_t *targ_n;
     947        stree_targ_t *targ;
     948
     949        targ_n = list_first(&csi->targ);
     950        while (targ_n != NULL) {
     951                targ = list_node_data(targ_n, stree_targ_t *);
     952                if (targ->name->sid == ident->sid)
     953                        return targ;
     954
     955                targ_n = list_next(&csi->targ, targ_n);
     956        }
     957
     958        /* No match */
     959        return NULL;
     960}
  • uspace/app/sbi/src/stree.h

    r80badbe r883fedc  
    3636stree_csi_t *stree_csi_new(csi_class_t cc);
    3737stree_csimbr_t *stree_csimbr_new(csimbr_class_t cc);
     38stree_deleg_t *stree_deleg_new(void);
    3839stree_fun_t *stree_fun_new(void);
    3940stree_var_t *stree_var_new(void);
    4041stree_prop_t *stree_prop_new(void);
     42stree_targ_t *stree_targ_new(void);
    4143
    4244stree_symbol_attr_t *stree_symbol_attr_new(symbol_attr_class_t sac);
     
    4446stree_proc_t *stree_proc_new(void);
    4547stree_proc_arg_t *stree_proc_arg_new(void);
     48stree_fun_sig_t *stree_fun_sig_new(void);
    4649stree_arg_attr_t *stree_arg_attr_new(arg_attr_class_t aac);
    4750
     
    6871stree_index_t *stree_index_new(void);
    6972stree_as_t *stree_as_new(void);
     73stree_box_t *stree_box_new(void);
    7074stree_nameref_t *stree_nameref_new(void);
    7175
     
    8791bool_t stree_arg_has_attr(stree_proc_arg_t *arg, arg_attr_class_t aac);
    8892bool_t stree_is_csi_derived_from_csi(stree_csi_t *a, stree_csi_t *b);
     93stree_targ_t *stree_csi_find_targ(stree_csi_t *csi, stree_ident_t *ident);
    8994
    9095#endif
  • uspace/app/sbi/src/stree_t.h

    r80badbe r883fedc  
    186186} stree_as_t;
    187187
     188/** Boxing of primitive type (pseudo)
     189 *
     190 * This pseudo-node is used internally to box a value of primitive type.
     191 * It is implicitly inserted by stype_convert(). It does not correspond
     192 * to a an explicit program construct.
     193 */
     194typedef struct {
     195        /* Primitive type expression */
     196        struct stree_expr *arg;
     197} stree_box_t;
     198
    188199/** Arithmetic expression class */
    189200typedef enum {
     
    198209        ec_assign,
    199210        ec_index,
    200         ec_as
     211        ec_as,
     212        ec_box
    201213} expr_class_t;
    202214
     
    219231                stree_assign_t *assign;
    220232                stree_as_t *as_op;
     233                stree_box_t *box;
    221234        } u;
    222235} stree_expr_t;
     
    415428} stree_proc_arg_t;
    416429
     430/** Function signature.
     431 *
     432 * Foormal parameters and return type. This is common to function and delegate
     433 * delcarations.
     434 */
     435typedef struct {
     436        /** Formal parameters */
     437        list_t args; /* of stree_proc_arg_t */
     438
     439        /** Variadic argument or @c NULL if none. */
     440        stree_proc_arg_t *varg;
     441
     442        /** Return type */
     443        stree_texpr_t *rtype;
     444} stree_fun_sig_t;
     445
    417446/** Procedure
    418447 *
     
    432461} stree_proc_t;
    433462
     463/** Delegate declaration */
     464typedef struct stree_deleg {
     465        /** Delegate name */
     466        stree_ident_t *name;
     467
     468        /** Symbol */
     469        struct stree_symbol *symbol;
     470
     471        /** Signature (arguments and return type) */
     472        stree_fun_sig_t *sig;
     473
     474        /** Type item describing the delegate */
     475        struct tdata_item *titem;
     476} stree_deleg_t;
     477
    434478/** Member function declaration */
    435479typedef struct stree_fun {
     
    440484        struct stree_symbol *symbol;
    441485
    442         /** Formal parameters */
    443         list_t args; /* of stree_proc_arg_t */
    444 
    445         /** Variadic argument or @c NULL if none. */
    446         stree_proc_arg_t *varg;
    447 
    448         /** Return type */
    449         stree_texpr_t *rtype;
     486        /** Signature (arguments and return type) */
     487        stree_fun_sig_t *sig;
    450488
    451489        /** Function implementation */
    452490        stree_proc_t *proc;
     491
     492        /** Type item describing the function */
     493        struct tdata_item *titem;
    453494} stree_fun_t;
    454495
     
    486527typedef enum {
    487528        csimbr_csi,
     529        csimbr_deleg,
    488530        csimbr_fun,
    489531        csimbr_var,
     
    497539        union {
    498540                struct stree_csi *csi;
     541                stree_deleg_t *deleg;
    499542                stree_fun_t *fun;
    500543                stree_var_t *var;
     
    509552} csi_class_t;
    510553
     554/** CSI formal type argument */
     555typedef struct stree_targ {
     556        stree_ident_t *name;
     557        struct stree_symbol *symbol;
     558} stree_targ_t;
     559
    511560/** Class, struct or interface declaration */
    512561typedef struct stree_csi {
     
    517566        stree_ident_t *name;
    518567
    519         /** List of type argument names */
    520         list_t targ_names; /* of stree_ident_t */
     568        /** List of type arguments */
     569        list_t targ; /* of stree_targ_t */
    521570
    522571        /** Symbol for this CSI */
     
    566615} stree_symbol_attr_t;
    567616
    568 
    569 typedef enum {
     617typedef enum {
     618        /** CSI (class, struct or interface) */
    570619        sc_csi,
     620        /** Member delegate */
     621        sc_deleg,
     622        /** Member function */
    571623        sc_fun,
     624        /** Member variable */
    572625        sc_var,
     626        /** Member property */
    573627        sc_prop
    574628} symbol_class_t;
     
    584638        union {
    585639                struct stree_csi *csi;
     640                stree_deleg_t *deleg;
    586641                stree_fun_t *fun;
    587642                stree_var_t *var;
  • uspace/app/sbi/src/strtab.c

    r80badbe r883fedc  
    3030 *
    3131 * Converts strings to more compact SID (string ID, integer) and back.
    32  * The string table is not an object as there will never be a need for
     32 * (The point is that this deduplicates the strings. Using SID might actually
     33 * not be such a big win.)
     34 *
     35 * The string table is a singleton as there will never be a need for
    3336 * more than one.
     37 *
     38 * Current implementation uses a linked list and thus it is slow.
    3439 */
    3540
     
    4348static list_t str_list;
    4449
     50/** Initialize string table. */
    4551void strtab_init(void)
    4652{
     
    4854}
    4955
     56/** Get SID of a string.
     57 *
     58 * Return SID of @a str. If @a str is not in the string table yet,
     59 * it is added and thus a new SID is assigned.
     60 *
     61 * @param str   String
     62 * @return      SID of @a str.
     63 */
    5064sid_t strtab_get_sid(const char *str)
    5165{
     
    7084}
    7185
     86/** Get string with the given SID.
     87 *
     88 * Returns string that has SID @a sid. If no such string exists, this
     89 * causes a fatal error in the interpreter.
     90 *
     91 * @param sid   SID of the string.
     92 * @return      Pointer to the string.
     93 */
    7294char *strtab_get_str(sid_t sid)
    7395{
  • uspace/app/sbi/src/stype.c

    r80badbe r883fedc  
    3030 * @file Implements a walk on the program that computes and checks static
    3131 * types. 'Types' the program.
     32 *
     33 * If a type error is encountered, stype_note_error() is called to set
     34 * the typing error flag.
    3235 */
    3336
     
    5356static void stype_prop(stype_t *stype, stree_prop_t *prop);
    5457
     58static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi,
     59    stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig);
     60static void stype_fun_body(stype_t *stype, stree_fun_t *fun);
    5561static void stype_block(stype_t *stype, stree_block_t *block);
    5662
     
    6470static void stype_wef(stype_t *stype, stree_wef_t *wef_s);
    6571
    66 /** Type module */
     72static stree_expr_t *stype_convert_tprimitive(stype_t *stype,
     73    stree_expr_t *expr, tdata_item_t *dest);
     74static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype,
     75    stree_expr_t *expr, tdata_item_t *dest);
     76static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr,
     77    tdata_item_t *dest);
     78static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr,
     79    tdata_item_t *dest);
     80static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr,
     81    tdata_item_t *dest);
     82static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype,
     83    stree_expr_t *expr, tdata_item_t *dest);
     84static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
     85    tdata_item_t *dest);
     86static void stype_convert_failure(stype_t *stype, tdata_item_t *src,
     87    tdata_item_t *dest);
     88
     89static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig,
     90    tdata_fun_sig_t *sdig);
     91
     92/** Type module.
     93 *
     94 * If the module contains a type error, @a stype->error will be set
     95 * when this function returns.
     96 *
     97 * @param stype         Static typing object
     98 * @param module        Module to type
     99 */
    67100void stype_module(stype_t *stype, stree_module_t *module)
    68101{
     
    87120}
    88121
    89 /** Type CSI */
     122/** Type CSI.
     123 *
     124 * @param stype         Static typing object
     125 * @param csi           CSI to type
     126 */
    90127static void stype_csi(stype_t *stype, stree_csi_t *csi)
    91128{
     
    108145                switch (csimbr->cc) {
    109146                case csimbr_csi: stype_csi(stype, csimbr->u.csi); break;
     147                case csimbr_deleg: stype_deleg(stype, csimbr->u.deleg); break;
    110148                case csimbr_fun: stype_fun(stype, csimbr->u.fun); break;
    111149                case csimbr_var: stype_var(stype, csimbr->u.var); break;
     
    119157}
    120158
    121 /** Type function */
     159/** Type delegate.
     160 *
     161 * @param stype         Static typing object.
     162 * @param deleg         Delegate to type.
     163 */
     164void stype_deleg(stype_t *stype, stree_deleg_t *deleg)
     165{
     166        stree_symbol_t *deleg_sym;
     167        tdata_item_t *deleg_ti;
     168        tdata_deleg_t *tdeleg;
     169        tdata_fun_sig_t *tsig;
     170
     171#ifdef DEBUG_TYPE_TRACE
     172        printf("Type delegate '");
     173        symbol_print_fqn(deleg_to_symbol(deleg));
     174        printf("'.\n");
     175#endif
     176        if (deleg->titem == NULL) {
     177                deleg_ti = tdata_item_new(tic_tdeleg);
     178                deleg->titem = deleg_ti;
     179                tdeleg = tdata_deleg_new();
     180                deleg_ti->u.tdeleg = tdeleg;
     181        } else {
     182                deleg_ti = deleg->titem;
     183                assert(deleg_ti->u.tdeleg != NULL);
     184                tdeleg = deleg_ti->u.tdeleg;
     185        }
     186
     187        if (tdeleg->tsig != NULL)
     188                return; /* Delegate has already been typed. */
     189
     190        deleg_sym = deleg_to_symbol(deleg);
     191
     192        /* Type function signature. Store result in deleg->titem. */
     193        stype_fun_sig(stype, deleg_sym->outer_csi, deleg->sig, &tsig);
     194
     195        tdeleg->deleg = deleg;
     196        tdeleg->tsig = tsig;
     197}
     198
     199/** Type function.
     200 *
     201 * We split typing of function header and body because at the point we
     202 * are typing the body of some function we may encounter function calls.
     203 * To type a function call we first need to type the header of the function
     204 * being called.
     205 *
     206 * @param stype         Static typing object.
     207 * @param fun           Function to type.
     208 */
    122209static void stype_fun(stype_t *stype, stree_fun_t *fun)
    123210{
    124         list_node_t *arg_n;
    125         stree_proc_arg_t *arg;
    126         stree_symbol_t *fun_sym;
    127         tdata_item_t *titem;
    128 
    129211#ifdef DEBUG_TYPE_TRACE
    130212        printf("Type function '");
     
    132214        printf("'.\n");
    133215#endif
     216        if (fun->titem == NULL)
     217                stype_fun_header(stype, fun);
     218
     219        stype_fun_body(stype, fun);
     220}
     221
     222/** Type function header.
     223 *
     224 * Types the header of @a fun (but not its body).
     225 *
     226 * @param stype         Static typing object
     227 * @param fun           Funtction
     228 */
     229void stype_fun_header(stype_t *stype, stree_fun_t *fun)
     230{
     231        stree_symbol_t *fun_sym;
     232        tdata_item_t *fun_ti;
     233        tdata_fun_t *tfun;
     234        tdata_fun_sig_t *tsig;
     235
     236#ifdef DEBUG_TYPE_TRACE
     237        printf("Type function '");
     238        symbol_print_fqn(fun_to_symbol(fun));
     239        printf("' header.\n");
     240#endif
     241        if (fun->titem != NULL)
     242                return; /* Function header has already been typed. */
     243
    134244        fun_sym = fun_to_symbol(fun);
     245
     246        /* Type function signature. */
     247        stype_fun_sig(stype, fun_sym->outer_csi, fun->sig, &tsig);
     248
     249        fun_ti = tdata_item_new(tic_tfun);
     250        tfun = tdata_fun_new();
     251        fun_ti->u.tfun = tfun;
     252        tfun->tsig = tsig;
     253
     254        fun->titem = fun_ti;
     255}
     256
     257/** Type function signature.
     258 *
     259 * Types the function signature @a sig.
     260 *
     261 * @param stype         Static typing object
     262 * @param outer_csi     CSI within which the signature is defined.
     263 * @param sig           Function signature
     264 */
     265static void stype_fun_sig(stype_t *stype, stree_csi_t *outer_csi,
     266    stree_fun_sig_t *sig, tdata_fun_sig_t **rtsig)
     267{
     268        list_node_t *arg_n;
     269        stree_proc_arg_t *arg;
     270        tdata_item_t *titem;
     271        tdata_fun_sig_t *tsig;
     272
     273#ifdef DEBUG_TYPE_TRACE
     274        printf("Type function signature.\n");
     275#endif
     276        tsig = tdata_fun_sig_new();
     277
     278        list_init(&tsig->arg_ti);
    135279
    136280        /*
    137281         * Type formal arguments.
    138          * XXX Save the results.
    139282         */
    140         arg_n = list_first(&fun->args);
     283        arg_n = list_first(&sig->args);
    141284        while (arg_n != NULL) {
    142285                arg = list_node_data(arg_n, stree_proc_arg_t *);
     
    144287                /* XXX Because of overloaded builtin WriteLine. */
    145288                if (arg->type == NULL) {
    146                         arg_n = list_next(&fun->args, arg_n);
     289                        list_append(&tsig->arg_ti, NULL);
     290                        arg_n = list_next(&sig->args, arg_n);
    147291                        continue;
    148292                }
    149293
    150                 run_texpr(stype->program, fun_sym->outer_csi, arg->type,
    151                     &titem);
    152 
    153                 arg_n = list_next(&fun->args, arg_n);
     294                run_texpr(stype->program, outer_csi, arg->type, &titem);
     295                list_append(&tsig->arg_ti, titem);
     296
     297                arg_n = list_next(&sig->args, arg_n);
    154298        }
    155299
    156300        /* Variadic argument */
    157         if (fun->varg != NULL) {
     301        if (sig->varg != NULL) {
    158302                /* Check type and verify it is an array. */
    159                 run_texpr(stype->program, fun_sym->outer_csi, fun->varg->type,
    160                     &titem);
     303                run_texpr(stype->program, outer_csi, sig->varg->type, &titem);
     304                tsig->varg_ti = titem;
    161305
    162306                if (titem->tic != tic_tarray && titem->tic != tic_ignore) {
     
    166310        }
    167311
    168         /*
    169          * Type function body.
    170          */
     312        /* Return type */
     313        if (sig->rtype != NULL) {
     314                run_texpr(stype->program, outer_csi, sig->rtype, &titem);
     315                tsig->rtype = titem;
     316        }
     317
     318        *rtsig = tsig;
     319}
     320
     321/** Type function body.
     322 *
     323 * Types the body of function @a fun (if it has one).
     324 *
     325 * @param stype         Static typing object
     326 * @param fun           Funtction
     327 */
     328static void stype_fun_body(stype_t *stype, stree_fun_t *fun)
     329{
     330#ifdef DEBUG_TYPE_TRACE
     331        printf("Type function '");
     332        symbol_print_fqn(fun_to_symbol(fun));
     333        printf("' body.\n");
     334#endif
     335        assert(stype->proc_vr == NULL);
    171336
    172337        /* Builtin functions do not have a body. */
     
    184349}
    185350
    186 /** Type member variable */
     351/** Type member variable.
     352 *
     353 * @param stype         Static typing object
     354 * @param var           Member variable
     355 */
    187356static void stype_var(stype_t *stype, stree_var_t *var)
    188357{
     
    201370}
    202371
    203 /** Type property */
     372/** Type property.
     373 *
     374 * @param stype         Static typing object
     375 * @param prop          Property
     376 */
    204377static void stype_prop(stype_t *stype, stree_prop_t *prop)
    205378{
     
    226399}
    227400
    228 /** Type statement block */
     401/** Type statement block.
     402 *
     403 * @param stype         Static typing object
     404 * @param block         Statement block
     405 */
    229406static void stype_block(stype_t *stype, stree_block_t *block)
    230407{
     
    265442 * for nested statemens). This is used in interactive mode.
    266443 *
    267  * @param stype         Static typer object.
    268  * @param stat          Statement to type.
    269  * @param want_value    @c b_true to allow ignoring expression value.
     444 * @param stype         Static typing object
     445 * @param stat          Statement to type
     446 * @param want_value    @c b_true to allow ignoring expression value
    270447 */
    271448void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value)
     
    286463}
    287464
    288 /** Type local variable declaration */
     465/** Type local variable declaration statement.
     466 *
     467 * @param stype         Static typing object
     468 * @param vdecl_s       Variable delcaration statement
     469 */
    289470static void stype_vdecl(stype_t *stype, stree_vdecl_t *vdecl_s)
    290471{
     
    317498}
    318499
    319 /** Type @c if statement */
     500/** Type @c if statement.
     501 *
     502 * @param stype         Static typing object
     503 * @param if_s          @c if statement
     504 */
    320505static void stype_if(stype_t *stype, stree_if_t *if_s)
    321506{
     
    340525}
    341526
    342 /** Type @c while statement */
     527/** Type @c while statement
     528 *
     529 * @param stype         Static typing object
     530 * @param while_s       @c while statement
     531 */
    343532static void stype_while(stype_t *stype, stree_while_t *while_s)
    344533{
     
    360549}
    361550
    362 /** Type @c for statement */
     551/** Type @c for statement.
     552 *
     553 * @param stype         Static typing object
     554 * @param for_s         @c for statement
     555 */
    363556static void stype_for(stype_t *stype, stree_for_t *for_s)
    364557{
     
    369562}
    370563
    371 /** Type @c raise statement */
     564/** Type @c raise statement.
     565 *
     566 * @param stype         Static typing object
     567 * @param raise_s       @c raise statement
     568 */
    372569static void stype_raise(stype_t *stype, stree_raise_t *raise_s)
    373570{
     
    402599
    403600                /* XXX Memoize to avoid recomputing. */
    404                 run_texpr(stype->program, outer_sym->outer_csi, fun->rtype,
    405                     &dtype);
     601                run_texpr(stype->program, outer_sym->outer_csi,
     602                    fun->sig->rtype, &dtype);
    406603                break;
    407604        case sc_prop:
     
    430627}
    431628
    432 /** Type expression statement */
     629/** Type expression statement.
     630 *
     631 * @param stype         Static typing object
     632 * @param exp_s         Expression statement
     633 */
    433634static void stype_exps(stype_t *stype, stree_exps_t *exp_s, bool_t want_value)
    434635{
     
    442643}
    443644
    444 /** Type With-Except-Finally statement */
     645/** Type with-except-finally statement.
     646 *
     647 * @param stype         Static typing object
     648 * @param wef_s         With-except-finally statement
     649 */
    445650static void stype_wef(stype_t *stype, stree_wef_t *wef_s)
    446651{
     
    482687 * Note: No conversion that would require modifying @a expr is implemented
    483688 * yet.
     689 *
     690 * @param stype         Static typing object
     691 * @param expr          Expression
     692 * @param dest          Destination type
    484693 */
    485694stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr,
     
    488697        tdata_item_t *src;
    489698
    490         (void) stype;
    491699        src = expr->titem;
     700
     701#ifdef DEBUG_TYPE_TRACE
     702        printf("Convert '");
     703        tdata_item_print(src);
     704        printf("' to '");
     705        tdata_item_print(dest);
     706        printf("'.\n");
     707#endif
    492708
    493709        if (dest == NULL) {
     
    514730        }
    515731
    516         if (src->tic != dest->tic)
    517                 goto failure;
     732        if (src->tic == tic_tprimitive && dest->tic == tic_tobject) {
     733                return stype_convert_tprim_tobj(stype, expr, dest);
     734        }
     735
     736        if (src->tic == tic_tfun && dest->tic == tic_tdeleg) {
     737                return stype_convert_tfun_tdeleg(stype, expr, dest);
     738        }
     739
     740        if (src->tic != dest->tic) {
     741                stype_convert_failure(stype, src, dest);
     742                return expr;
     743        }
    518744
    519745        switch (src->tic) {
    520746        case tic_tprimitive:
    521                 /* Check if both have the same tprimitive class. */
    522                 if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc)
    523                         goto failure;
     747                expr = stype_convert_tprimitive(stype, expr, dest);
    524748                break;
    525749        case tic_tobject:
    526                 /* Check if @c src is derived from @c dest. */
    527                 if (stree_is_csi_derived_from_csi(src->u.tobject->csi,
    528                     dest->u.tobject->csi) != b_true) {
    529                         goto failure;
    530                 }
     750                expr = stype_convert_tobject(stype, expr, dest);
    531751                break;
    532752        case tic_tarray:
    533                 /* Compare rank and base type. */
    534                 if (src->u.tarray->rank != dest->u.tarray->rank)
    535                         goto failure;
    536 
    537                 /* XXX Should we convert each element? */
    538                 if (tdata_item_equal(src->u.tarray->base_ti,
    539                     dest->u.tarray->base_ti) != b_true)
    540                         goto failure;
     753                expr = stype_convert_tarray(stype, expr, dest);
     754                break;
     755        case tic_tdeleg:
     756                expr = stype_convert_tdeleg(stype, expr, dest);
    541757                break;
    542758        case tic_tfun:
    543                 printf("Error: Unimplemented: Converting '");
    544                 tdata_item_print(src);
    545                 printf("' to '");
    546                 tdata_item_print(dest);
    547                 printf("'.\n");
    548                 stype_note_error(stype);
     759                assert(b_false);
     760        case tic_tvref:
     761                expr = stype_convert_tvref(stype, expr, dest);
    549762                break;
    550763        case tic_ignore:
     
    553766
    554767        return expr;
    555 
    556 failure:
     768}
     769
     770/** Convert expression of primitive type to primitive type.
     771 *
     772 * @param stype         Static typing object
     773 * @param expr          Expression
     774 * @param dest          Destination type
     775 */
     776static stree_expr_t *stype_convert_tprimitive(stype_t *stype,
     777    stree_expr_t *expr, tdata_item_t *dest)
     778{
     779        tdata_item_t *src;
     780
     781#ifdef DEBUG_TYPE_TRACE
     782        printf("Convert primitive type.\n");
     783#endif
     784        src = expr->titem;
     785        assert(src->tic == tic_tprimitive);
     786        assert(dest->tic == tic_tprimitive);
     787
     788        /* Check if both have the same tprimitive class. */
     789        if (src->u.tprimitive->tpc != dest->u.tprimitive->tpc)
     790                stype_convert_failure(stype, src, dest);
     791
     792        return expr;
     793}
     794
     795/** Convert expression of primitive type to object type.
     796 *
     797 * This function implements autoboxing. It modified the code.
     798 *
     799 * @param stype         Static typing object
     800 * @param expr          Expression
     801 * @param dest          Destination type
     802 */
     803static stree_expr_t *stype_convert_tprim_tobj(stype_t *stype,
     804    stree_expr_t *expr, tdata_item_t *dest)
     805{
     806        tdata_item_t *src;
     807        builtin_t *bi;
     808        stree_symbol_t *csi_sym;
     809        stree_symbol_t *bp_sym;
     810        stree_box_t *box;
     811        stree_expr_t *bexpr;
     812
     813#ifdef DEBUG_TYPE_TRACE
     814        printf("Convert primitive type to object.\n");
     815#endif
     816        src = expr->titem;
     817        assert(src->tic == tic_tprimitive);
     818        assert(dest->tic == tic_tobject);
     819
     820        bi = stype->program->builtin;
     821        csi_sym = csi_to_symbol(dest->u.tobject->csi);
     822
     823        switch (src->u.tprimitive->tpc) {
     824        case tpc_bool: bp_sym = bi->boxed_bool; break;
     825        case tpc_char: bp_sym = bi->boxed_char; break;
     826        case tpc_int: bp_sym = bi->boxed_int; break;
     827        case tpc_nil: assert(b_false);
     828        case tpc_string: bp_sym = bi->boxed_string; break;
     829        case tpc_resource:
     830                stype_convert_failure(stype, src, dest);
     831                return expr;
     832        }
     833
     834        /* Target type must be boxed @a src or Object */
     835        if (csi_sym != bp_sym && csi_sym != bi->gf_class)
     836                stype_convert_failure(stype, src, dest);
     837
     838        /* Patch the code to box the primitive value */
     839        box = stree_box_new();
     840        box->arg = expr;
     841        bexpr = stree_expr_new(ec_box);
     842        bexpr->u.box = box;
     843
     844        /* No action needed to optionally convert boxed type to Object */
     845
     846        return bexpr;
     847}
     848
     849/** Convert expression of object type to object type.
     850 *
     851 * @param stype         Static typing object
     852 * @param expr          Expression
     853 * @param dest          Destination type
     854 */
     855static stree_expr_t *stype_convert_tobject(stype_t *stype, stree_expr_t *expr,
     856    tdata_item_t *dest)
     857{
     858        tdata_item_t *src;
     859        tdata_item_t *cur;
     860        stree_csi_t *cur_csi;
     861        tdata_tvv_t *tvv;
     862        tdata_item_t *b_ti, *bs_ti;
     863
     864#ifdef DEBUG_TYPE_TRACE
     865        printf("Convert object type.\n");
     866#endif
     867        list_node_t *ca_n, *da_n;
     868        tdata_item_t *carg, *darg;
     869
     870        src = expr->titem;
     871        assert(src->tic == tic_tobject);
     872        assert(dest->tic == tic_tobject);
     873
     874        cur = src;
     875
     876        while (cur->u.tobject->csi != dest->u.tobject->csi) {
     877
     878                cur_csi = cur->u.tobject->csi;
     879                stype_titem_to_tvv(stype, cur, &tvv);
     880
     881                if (cur_csi->base_csi_ref != NULL) {
     882                        run_texpr(stype->program, cur_csi, cur_csi->base_csi_ref, &b_ti);
     883                        if (b_ti->tic == tic_ignore) {
     884                                /* An error occured. */
     885                                stype_note_error(stype);
     886                                return expr;
     887                        }
     888
     889                        tdata_item_subst(b_ti, tvv, &bs_ti);
     890                        cur = bs_ti;
     891                        assert(cur->tic == tic_tobject);
     892
     893                } else if (cur_csi->base_csi != NULL) {
     894                        /* No explicit reference. Use grandfather class. */
     895                        cur = tdata_item_new(tic_tobject);
     896                        cur->u.tobject = tdata_object_new();
     897                        cur->u.tobject->csi = cur_csi->base_csi;
     898                        cur->u.tobject->static_ref = b_false;
     899
     900                        list_init(&cur->u.tobject->targs);
     901                } else {
     902                        /* No match */
     903                        stype_convert_failure(stype, src, dest);
     904                        return expr;
     905                }
     906        }
     907
     908        /* Verify that type arguments match */
     909        ca_n = list_first(&cur->u.tobject->targs);
     910        da_n = list_first(&dest->u.tobject->targs);
     911
     912        while (ca_n != NULL && da_n != NULL) {
     913                carg = list_node_data(ca_n, tdata_item_t *);
     914                darg = list_node_data(da_n, tdata_item_t *);
     915
     916                if (tdata_item_equal(carg, darg) != b_true) {
     917                        /* Diferent argument type */
     918                        stype_convert_failure(stype, src, dest);
     919                        printf("Different argument type '");
     920                        tdata_item_print(carg);
     921                        printf("' vs. '");
     922                        tdata_item_print(darg);
     923                        printf("'.\n");
     924                        return expr;
     925                }
     926
     927                ca_n = list_next(&cur->u.tobject->targs, ca_n);
     928                da_n = list_next(&dest->u.tobject->targs, da_n);
     929        }
     930
     931        if (ca_n != NULL || da_n != NULL) {
     932                /* Diferent number of arguments */
     933                stype_convert_failure(stype, src, dest);
     934                printf("Different number of arguments.\n");
     935                return expr;
     936        }
     937
     938        return expr;
     939}
     940
     941/** Convert expression of array type to array type.
     942 *
     943 * @param stype         Static typing object
     944 * @param expr          Expression
     945 * @param dest          Destination type
     946 */
     947static stree_expr_t *stype_convert_tarray(stype_t *stype, stree_expr_t *expr,
     948    tdata_item_t *dest)
     949{
     950        tdata_item_t *src;
     951
     952#ifdef DEBUG_TYPE_TRACE
     953        printf("Convert array type.\n");
     954#endif
     955        src = expr->titem;
     956        assert(src->tic == tic_tarray);
     957        assert(dest->tic == tic_tarray);
     958
     959        /* Compare rank and base type. */
     960        if (src->u.tarray->rank != dest->u.tarray->rank) {
     961                stype_convert_failure(stype, src, dest);
     962                return expr;
     963        }
     964
     965        /* XXX Should we convert each element? */
     966        if (tdata_item_equal(src->u.tarray->base_ti,
     967            dest->u.tarray->base_ti) != b_true) {
     968                stype_convert_failure(stype, src, dest);
     969        }
     970
     971        return expr;
     972}
     973
     974/** Convert expression of delegate type to delegate type.
     975 *
     976 * @param stype         Static typing object
     977 * @param expr          Expression
     978 * @param dest          Destination type
     979 */
     980static stree_expr_t *stype_convert_tdeleg(stype_t *stype, stree_expr_t *expr,
     981    tdata_item_t *dest)
     982{
     983        tdata_item_t *src;
     984        tdata_deleg_t *sdeleg, *ddeleg;
     985
     986#ifdef DEBUG_TYPE_TRACE
     987        printf("Convert delegate type.\n");
     988#endif
     989        src = expr->titem;
     990        assert(src->tic == tic_tdeleg);
     991        assert(dest->tic == tic_tdeleg);
     992
     993        sdeleg = src->u.tdeleg;
     994        ddeleg = dest->u.tdeleg;
     995
     996        /*
     997         * XXX We need to redesign handling of generic types to handle
     998         * delegates in generic CSIs properly.
     999         */
     1000
     1001        /* Destination should never be anonymous delegate. */
     1002        assert(ddeleg->deleg != NULL);
     1003
     1004        /* Both must be the same delegate. */
     1005        if (sdeleg->deleg != ddeleg->deleg) {
     1006                stype_convert_failure(stype, src, dest);
     1007                return expr;
     1008        }
     1009
     1010        return expr;
     1011}
     1012
     1013/** Convert expression of function type to delegate type.
     1014 *
     1015 * @param stype         Static typing object
     1016 * @param expr          Expression
     1017 * @param dest          Destination type
     1018 */
     1019static stree_expr_t *stype_convert_tfun_tdeleg(stype_t *stype,
     1020    stree_expr_t *expr, tdata_item_t *dest)
     1021{
     1022        tdata_item_t *src;
     1023        tdata_fun_t *sfun;
     1024        tdata_deleg_t *ddeleg;
     1025        tdata_fun_sig_t *ssig, *dsig;
     1026
     1027#ifdef DEBUG_TYPE_TRACE
     1028        printf("Convert delegate type.\n");
     1029#endif
     1030        src = expr->titem;
     1031        assert(src->tic == tic_tfun);
     1032        assert(dest->tic == tic_tdeleg);
     1033
     1034        sfun = src->u.tfun;
     1035        ddeleg = dest->u.tdeleg;
     1036
     1037        ssig = sfun->tsig;
     1038        assert(ssig != NULL);
     1039        dsig = stype_deleg_get_sig(stype, ddeleg);
     1040        assert(dsig != NULL);
     1041
     1042        /* Signature type must match. */
     1043
     1044        if (!stype_fun_sig_equal(stype, ssig, dsig)) {
     1045                stype_convert_failure(stype, src, dest);
     1046                return expr;
     1047        }
     1048
     1049        /*
     1050         * XXX We should also compare attributes. Either the
     1051         * tdeleg should be extended or we should get them
     1052         * from stree_deleg.
     1053         */
     1054
     1055        return expr;
     1056}
     1057
     1058
     1059/** Convert expression of variable type to variable type.
     1060 *
     1061 * @param stype         Static typing object
     1062 * @param expr          Expression
     1063 * @param dest          Destination type
     1064 */
     1065static stree_expr_t *stype_convert_tvref(stype_t *stype, stree_expr_t *expr,
     1066    tdata_item_t *dest)
     1067{
     1068        tdata_item_t *src;
     1069
     1070#ifdef DEBUG_TYPE_TRACE
     1071        printf("Convert variable type.\n");
     1072#endif
     1073        src = expr->titem;
     1074
     1075        /* Currently only allow if both types are the same. */
     1076        if (src->u.tvref->targ != dest->u.tvref->targ) {
     1077                stype_convert_failure(stype, src, dest);
     1078                return expr;
     1079        }
     1080
     1081        return expr;
     1082}
     1083
     1084/** Display conversion error message and note error.
     1085 *
     1086 * @param stype         Static typing object
     1087 * @param src           Original type
     1088 * @param dest          Destination type
     1089 */
     1090static void stype_convert_failure(stype_t *stype, tdata_item_t *src,
     1091    tdata_item_t *dest)
     1092{
    5571093        printf("Error: Cannot convert ");
    5581094        tdata_item_print(src);
     
    5621098
    5631099        stype_note_error(stype);
    564         return expr;
    565 }
    566 
    567 /** Return a boolean type item */
     1100}
     1101
     1102/** Determine if two type signatures are equal.
     1103 *
     1104 * XXX This does not compare the attributes, which are missing from
     1105 * @c tdata_fun_sig_t.
     1106 *
     1107 * @param stype         Static typing object
     1108 * @param asig          First function signature type
     1109 * @param bsig          Second function signature type
     1110 */
     1111static bool_t stype_fun_sig_equal(stype_t *stype, tdata_fun_sig_t *asig,
     1112    tdata_fun_sig_t *bsig)
     1113{
     1114        list_node_t *aarg_n, *barg_n;
     1115        tdata_item_t *aarg_ti, *barg_ti;
     1116
     1117        (void) stype;
     1118
     1119        /* Compare types of arguments */
     1120        aarg_n = list_first(&asig->arg_ti);
     1121        barg_n = list_first(&bsig->arg_ti);
     1122
     1123        while (aarg_n != NULL && barg_n != NULL) {
     1124                aarg_ti = list_node_data(aarg_n, tdata_item_t *);
     1125                barg_ti = list_node_data(barg_n, tdata_item_t *);
     1126
     1127                if (!tdata_item_equal(aarg_ti, barg_ti))
     1128                        return b_false;
     1129
     1130                aarg_n = list_next(&asig->arg_ti, aarg_n);
     1131                barg_n = list_next(&bsig->arg_ti, barg_n);
     1132        }
     1133
     1134        if (aarg_n != NULL || barg_n != NULL)
     1135                return b_false;
     1136
     1137        /* Compare variadic argument */
     1138
     1139        if (asig->varg_ti != NULL || bsig->varg_ti != NULL) {
     1140                if (asig->varg_ti == NULL ||
     1141                    bsig->varg_ti == NULL) {
     1142                        return b_false;
     1143                }
     1144
     1145                if (!tdata_item_equal(asig->varg_ti, bsig->varg_ti)) {
     1146                        return b_false;
     1147                }
     1148        }
     1149
     1150        /* Compare return type */
     1151        if (!tdata_item_equal(asig->rtype, bsig->rtype))
     1152                return b_false;
     1153
     1154        return b_true;
     1155}
     1156
     1157/** Get function signature from delegate.
     1158 *
     1159 * Function signature can be missing if the delegate type is incomplete.
     1160 * This is used to break circular dependency when typing delegates.
     1161 * If this happens, we type the delegate, which gives us the signature.
     1162 */
     1163tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg)
     1164{
     1165        if (tdeleg->tsig == NULL)
     1166                stype_deleg(stype, tdeleg->deleg);
     1167
     1168        /* Now we should have a signature. */
     1169        assert(tdeleg->tsig != NULL);
     1170        return tdeleg->tsig;
     1171}
     1172
     1173/** Convert tic_tobject type item to TVV,
     1174 *
     1175 * We split generic type application into two steps. In the first step
     1176 * we match argument names of @a ti->csi to argument values in @a ti
     1177 * to produce a TVV (name to value map for type arguments). That is the
     1178 * purpose of this function.
     1179 *
     1180 * In the second step we substitute variables in another type item
     1181 * with their values using the TVV. This is performed by tdata_item_subst().
     1182 *
     1183 * @param stype         Static typing object.
     1184 * @param ti            Type item of class tic_tobject.
     1185 * @param rtvv          Place to store pointer to new TVV.
     1186 */
     1187void stype_titem_to_tvv(stype_t *stype, tdata_item_t *ti, tdata_tvv_t **rtvv)
     1188{
     1189        tdata_tvv_t *tvv;
     1190        stree_csi_t *csi;
     1191
     1192        list_node_t *formal_n;
     1193        list_node_t *real_n;
     1194
     1195        stree_targ_t *formal_arg;
     1196        tdata_item_t *real_arg;
     1197
     1198        assert(ti->tic == tic_tobject);
     1199
     1200        tvv = tdata_tvv_new();
     1201        intmap_init(&tvv->tvv);
     1202
     1203        csi = ti->u.tobject->csi;
     1204        formal_n = list_first(&csi->targ);
     1205        real_n = list_first(&ti->u.tobject->targs);
     1206
     1207        while (formal_n != NULL && real_n != NULL) {
     1208                formal_arg = list_node_data(formal_n, stree_targ_t *);
     1209                real_arg = list_node_data(real_n, tdata_item_t *);
     1210
     1211                /* Store argument value into valuation. */
     1212                tdata_tvv_set_val(tvv, formal_arg->name->sid, real_arg);
     1213
     1214                formal_n = list_next(&csi->targ, formal_n);
     1215                real_n = list_next(&ti->u.tobject->targs, real_n);
     1216        }
     1217
     1218        if (formal_n != NULL || real_n != NULL) {
     1219                printf("Error: Incorrect number of type arguments.\n");
     1220                stype_note_error(stype);
     1221
     1222                /* Fill missing arguments with recovery type items. */
     1223                while (formal_n != NULL) {
     1224                        formal_arg = list_node_data(formal_n, stree_targ_t *);
     1225                        /* Store recovery value into valuation. */
     1226                        tdata_tvv_set_val(tvv, formal_arg->name->sid,
     1227                            stype_recovery_titem(stype));
     1228
     1229                        formal_n = list_next(&csi->targ, formal_n);
     1230                }
     1231        }
     1232
     1233        *rtvv = tvv;
     1234}
     1235
     1236/** Return a boolean type item.
     1237 *
     1238 * @param stype         Static typing object
     1239 * @return              New boolean type item.
     1240 */
    5681241tdata_item_t *stype_boolean_titem(stype_t *stype)
    5691242{
     
    5801253}
    5811254
    582 /** Find a local variable in the current function. */
     1255/** Find a local variable in the current function.
     1256 *
     1257 * @param stype         Static typing object
     1258 * @param name          Name of variable (SID).
     1259 * @return              Pointer to variable declaration or @c NULL if not
     1260 *                      found.
     1261 */
    5831262stree_vdecl_t *stype_local_vars_lookup(stype_t *stype, sid_t name)
    5841263{
     
    6051284}
    6061285
    607 /** Find argument of the current procedure. */
     1286/** Find argument of the current procedure.
     1287 *
     1288 * @param stype         Static typing object
     1289 * @param name          Name of argument (SID).
     1290 * @return              Pointer to argument declaration or @c NULL if not
     1291 *                      found.
     1292 */
    6081293stree_proc_arg_t *stype_proc_args_lookup(stype_t *stype, sid_t name)
    6091294{
     
    6331318                fun = symbol_to_fun(outer_sym);
    6341319                assert(fun != NULL);
    635                 args = &fun->args;
    636                 varg = fun->varg;
     1320                args = &fun->sig->args;
     1321                varg = fun->sig->varg;
    6371322                break;
    6381323        case sc_prop:
     
    6881373}
    6891374
    690 /** Note a static typing error that has been immediately recovered. */
     1375/** Note a static typing error that has been immediately recovered.
     1376 *
     1377 * @param stype         Static typing object
     1378 */
    6911379void stype_note_error(stype_t *stype)
    6921380{
     
    6941382}
    6951383
    696 /** Construct a special type item for recovery. */
     1384/** Construct a special type item for recovery.
     1385 *
     1386 * The recovery item is propagated towards the expression root and causes
     1387 * any further typing errors in the expression to be supressed.
     1388 *
     1389 * @param stype         Static typing object
     1390 */
    6971391tdata_item_t *stype_recovery_titem(stype_t *stype)
    6981392{
     
    7051399}
    7061400
    707 /** Get current block visit record. */
     1401/** Get current block visit record.
     1402 *
     1403 * @param stype         Static typing object
     1404 */
    7081405stype_block_vr_t *stype_get_current_block_vr(stype_t *stype)
    7091406{
     
    7141411}
    7151412
     1413/** Allocate new procedure visit record.
     1414 *
     1415 * @return      New procedure VR
     1416 */
    7161417stype_proc_vr_t *stype_proc_vr_new(void)
    7171418{
     
    7271428}
    7281429
     1430/** Allocate new block visit record.
     1431 *
     1432 * @return      New block VR
     1433 */
    7291434stype_block_vr_t *stype_block_vr_new(void)
    7301435{
  • uspace/app/sbi/src/stype.h

    r80badbe r883fedc  
    3333
    3434void stype_module(stype_t *stype, stree_module_t *module);
     35void stype_deleg(stype_t *stype, stree_deleg_t *deleg);
     36void stype_fun_header(stype_t *stype, stree_fun_t *fun);
    3537void stype_stat(stype_t *stype, stree_stat_t *stat, bool_t want_value);
    3638
     
    4042stree_expr_t *stype_convert(stype_t *stype, stree_expr_t *expr,
    4143    tdata_item_t *dest);
     44
     45tdata_fun_sig_t *stype_deleg_get_sig(stype_t *stype, tdata_deleg_t *tdeleg);
     46
     47void stype_titem_to_tvv(stype_t *stype, tdata_item_t *ti, tdata_tvv_t **rtvv);
    4248
    4349tdata_item_t *stype_boolean_titem(stype_t *stype);
  • uspace/app/sbi/src/stype_expr.c

    r80badbe r883fedc  
    2727 */
    2828
    29 /** @file Type expressions. */
     29/** @file Typing of expressions.
     30 *
     31 * This module types (data) expressions -- not to be confused with evaluating
     32 * type expressions! Thus the type of each (sub-)expression is determined
     33 * and stored in its @c titem field.
     34 *
     35 * It can also happen that, due to implicit conversions, the expression
     36 * needs to be patched to insert these conversions.
     37 *
     38 * If a type error occurs within an expression, @c stype->error is set
     39 * and the type of the expression will be @c tic_ignore. This type item
     40 * is propagated upwards and causes further typing errors to be ignored
     41 * (this prevents a type error avalanche). Type checking is thus resumed
     42 * at the next expression.
     43 */
    3044
    3145#include <stdio.h>
     
    103117    tdata_item_t **rtitem);
    104118static void stype_as(stype_t *stype, stree_as_t *as_op, tdata_item_t **rtitem);
    105 
    106 
    107 /** Type expression. */
     119static void stype_box(stype_t *stype, stree_box_t *box, tdata_item_t **rtitem);
     120
     121
     122/** Type expression
     123 *
     124 * The type is stored in @a expr->titem. If the express contains a type error,
     125 * @a stype->error will be set when this function returns.
     126 *
     127 * @param stype         Static typing object
     128 * @param expr          Expression
     129 */
    108130void stype_expr(stype_t *stype, stree_expr_t *expr)
    109131{
     
    128150        case ec_assign: stype_assign(stype, expr->u.assign, &et); break;
    129151        case ec_as: stype_as(stype, expr->u.as_op, &et); break;
     152        case ec_box: stype_box(stype, expr->u.box, &et); break;
    130153        }
    131154
     
    139162}
    140163
    141 /** Type name reference. */
     164/** Type name reference.
     165 *
     166 * @param stype         Static typing object
     167 * @param nameref       Name reference
     168 * @param rtitem        Place to store result type
     169 */
    142170static void stype_nameref(stype_t *stype, stree_nameref_t *nameref,
    143171    tdata_item_t **rtitem)
     
    149177        tdata_object_t *tobject;
    150178        stree_csi_t *csi;
     179        stree_deleg_t *deleg;
    151180        stree_fun_t *fun;
    152181
     
    231260                tobject->csi = csi;
    232261                break;
     262        case sc_deleg:
     263                printf("referenced name is deleg\n");
     264                deleg = symbol_to_deleg(sym);
     265                assert(deleg != NULL);
     266                /* Type delegate if it has not been typed yet. */
     267                stype_deleg(stype, deleg);
     268                titem = deleg->titem;
     269                break;
    233270        case sc_fun:
    234271                fun = symbol_to_fun(sym);
    235272                assert(fun != NULL);
    236 
    237                 titem = tdata_item_new(tic_tfun);
    238                 titem->u.tfun = tdata_fun_new();
    239                 titem->u.tfun->fun = fun;
     273                /* Type function header if it has not been typed yet. */
     274                stype_fun_header(stype, fun);
     275                titem = fun->titem;
    240276                break;
    241277        }
     
    244280}
    245281
    246 /** Type a literal. */
     282/** Type a literal.
     283 *
     284 * @param stype         Static typing object
     285 * @param literal       Literal
     286 * @param rtitem        Place to store result type
     287 */
    247288static void stype_literal(stype_t *stype, stree_literal_t *literal,
    248289    tdata_item_t **rtitem)
     
    272313}
    273314
    274 /** Type a self reference. */
     315/** Type @c self reference.
     316 *
     317 * @param stype         Static typing object
     318 * @param self_ref      @c self reference
     319 * @param rtitem        Place to store result type
     320 */
    275321static void stype_self_ref(stype_t *stype, stree_self_ref_t *self_ref,
    276322    tdata_item_t **rtitem)
     
    285331}
    286332
    287 /** Type a binary operation. */
     333/** Type a binary operation.
     334 *
     335 * @param stype         Static typing object
     336 * @param binop         Binary operation
     337 * @param rtitem        Place to store result type
     338 */
    288339static void stype_binop(stype_t *stype, stree_binop_t *binop,
    289340    tdata_item_t **rtitem)
     
    345396}
    346397
    347 /** Type a binary operation with arguments of primitive type. */
     398/** Type a binary operation with arguments of primitive type.
     399 *
     400 * @param stype         Static typing object
     401 * @param binop         Binary operation
     402 * @param ta            Type of first argument
     403 * @param tb            Type of second argument
     404 * @param rtitem        Place to store result type
     405 */
    348406static void stype_binop_tprimitive(stype_t *stype, stree_binop_t *binop,
    349407    tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem)
     
    374432}
    375433
    376 /** Type a binary operation with bool arguments. */
     434/** Type a binary operation with @c bool arguments.
     435 *
     436 * @param stype         Static typing object
     437 * @param binop         Binary operation
     438 * @param rtitem        Place to store result type
     439 */
    377440static void stype_binop_bool(stype_t *stype, stree_binop_t *binop,
    378441    tdata_item_t **rtitem)
     
    408471}
    409472
    410 /** Type a binary operation with char arguments. */
     473/** Type a binary operation with @c char arguments.
     474 *
     475 * @param stype         Static typing object
     476 * @param binop         Binary operation
     477 * @param rtitem        Place to store result type
     478 */
    411479static void stype_binop_char(stype_t *stype, stree_binop_t *binop,
    412480    tdata_item_t **rtitem)
     
    444512}
    445513
    446 /** Type a binary operation with int arguments. */
     514/** Type a binary operation with @c int arguments.
     515 *
     516 * @param stype         Static typing object
     517 * @param binop         Binary operation
     518 * @param rtitem        Place to store result type
     519 */
    447520static void stype_binop_int(stype_t *stype, stree_binop_t *binop,
    448521    tdata_item_t **rtitem)
     
    477550}
    478551
    479 /** Type a binary operation with nil arguments. */
     552/** Type a binary operation with @c nil arguments.
     553 *
     554 * @param stype         Static typing object
     555 * @param binop         Binary operation
     556 * @param rtitem        Place to store result type
     557 */
    480558static void stype_binop_nil(stype_t *stype, stree_binop_t *binop,
    481559    tdata_item_t **rtitem)
     
    488566}
    489567
    490 /** Type a binary operation with string arguments. */
     568/** Type a binary operation with @c string arguments.
     569 *
     570 * @param stype         Static typing object
     571 * @param binop         Binary operation
     572 * @param rtitem        Place to store result type
     573 */
    491574static void stype_binop_string(stype_t *stype, stree_binop_t *binop,
    492575    tdata_item_t **rtitem)
     
    511594}
    512595
    513 /** Type a binary operation with resource arguments. */
     596/** Type a binary operation with resource arguments.
     597 *
     598 * @param stype         Static typing object
     599 * @param binop         Binary operation
     600 * @param rtitem        Place to store result type
     601 */
    514602static void stype_binop_resource(stype_t *stype, stree_binop_t *binop,
    515603    tdata_item_t **rtitem)
     
    530618}
    531619
    532 /** Type a binary operation with arguments of an object type. */
     620/** Type a binary operation with arguments of an object type.
     621 *
     622 * @param stype         Static typing object
     623 * @param binop         Binary operation
     624 * @param ta            Type of first argument
     625 * @param tb            Type of second argument
     626 * @param rtitem        Place to store result type
     627 */
    533628static void stype_binop_tobject(stype_t *stype, stree_binop_t *binop,
    534629    tdata_item_t *ta, tdata_item_t *tb, tdata_item_t **rtitem)
     
    561656
    562657
    563 /** Type a unary operation. */
     658/** Type a unary operation.
     659 *
     660 * @param stype         Static typing object
     661 * @param unop          Unary operation
     662 * @param rtitem        Place to store result type
     663*/
    564664static void stype_unop(stype_t *stype, stree_unop_t *unop,
    565665    tdata_item_t **rtitem)
     
    594694}
    595695
    596 /** Type a binary operation arguments of primitive type. */
     696/** Type a binary operation arguments of primitive type.
     697 *
     698 * @param stype         Static typing object
     699 * @param unop          Binary operation
     700 * @param ta            Type of argument
     701 * @param rtitem        Place to store result type
     702 */
    597703static void stype_unop_tprimitive(stype_t *stype, stree_unop_t *unop,
    598704    tdata_item_t *ta, tdata_item_t **rtitem)
     
    627733}
    628734
    629 /** Type a @c new operation. */
     735/** Type a @c new operation.
     736 *
     737 * @param stype         Static typing object
     738 * @param new_op        @c new operation
     739 * @param rtitem        Place to store result type
     740 */
    630741static void stype_new(stype_t *stype, stree_new_t *new_op,
    631742    tdata_item_t **rtitem)
     
    646757}
    647758
    648 /** Type a field access operation */
     759/** Type a member access operation.
     760 *
     761 * @param stype         Static typing object
     762 * @param access        Member access operation
     763 * @param rtitem        Place to store result type
     764 */
    649765static void stype_access(stype_t *stype, stree_access_t *access,
    650766    tdata_item_t **rtitem)
     
    675791                stype_access_tarray(stype, access, arg_ti, rtitem);
    676792                break;
     793        case tic_tdeleg:
     794                printf("Error: Using '.' operator on a function.\n");
     795                stype_note_error(stype);
     796                *rtitem = stype_recovery_titem(stype);
     797                break;
    677798        case tic_tfun:
    678                 printf("Error: Using '.' operator on a function.\n");
    679                 stype_note_error(stype);
     799                printf("Error: Using '.' operator on a delegate.\n");
     800                stype_note_error(stype);
     801                *rtitem = stype_recovery_titem(stype);
     802                break;
     803        case tic_tvref:
     804                /* Cannot allow this without some constraint. */
     805                printf("Error: Using '.' operator on generic data.\n");
    680806                *rtitem = stype_recovery_titem(stype);
    681807                break;
     
    686812}
    687813
    688 /** Type a primitive type access operation. */
     814/** Type a primitive type access operation.
     815 *
     816 * @param stype         Static typing object
     817 * @param access        Member access operation
     818 * @param arg_ti        Base type
     819 * @param rtitem        Place to store result type
     820 */
    689821static void stype_access_tprimitive(stype_t *stype, stree_access_t *access,
    690822    tdata_item_t *arg_ti, tdata_item_t **rtitem)
     
    701833}
    702834
    703 /** Type an object access operation. */
     835/** Type an object access operation.
     836 *
     837 * @param stype         Static typing object
     838 * @param access        Member access operation
     839 * @param arg_ti        Base type
     840 * @param rtitem        Place to store result type
     841*/
    704842static void stype_access_tobject(stype_t *stype, stree_access_t *access,
    705843    tdata_item_t *arg_ti, tdata_item_t **rtitem)
     
    710848        stree_prop_t *prop;
    711849        tdata_object_t *tobject;
     850        tdata_item_t *mtitem;
     851        tdata_tvv_t *tvv;
    712852
    713853#ifdef DEBUG_TYPE_TRACE
     
    743883                stype_note_error(stype);
    744884                *rtitem = stype_recovery_titem(stype);
    745                 break;
     885                return;
     886        case sc_deleg:
     887                printf("Error: Accessing object member which is a "
     888                    "delegate.\n");
     889                stype_note_error(stype);
     890                *rtitem = stype_recovery_titem(stype);
     891                return;
    746892        case sc_fun:
    747893                fun = symbol_to_fun(member_sym);
    748894                assert(fun != NULL);
    749                 *rtitem = tdata_item_new(tic_tfun);
    750                 (*rtitem)->u.tfun = tdata_fun_new();
    751                 (*rtitem)->u.tfun->fun = fun;
     895                /* Type function header now */
     896                stype_fun_header(stype, fun);
     897                mtitem = fun->titem;
    752898                break;
    753899        case sc_var:
    754900                var = symbol_to_var(member_sym);
    755901                assert(var != NULL);
    756                 /* XXX Memoize to avoid recomputing every time. */
    757902                run_texpr(stype->program, member_sym->outer_csi,
    758                     var->type, rtitem);
     903                    var->type, &mtitem);
    759904                break;
    760905        case sc_prop:
    761906                prop = symbol_to_prop(member_sym);
    762907                assert(prop != NULL);
    763                 /* XXX Memoize to avoid recomputing every time. */
    764908                run_texpr(stype->program, member_sym->outer_csi,
    765                     prop->type, rtitem);
    766                 break;
    767         }
    768 }
    769 
    770 /** Type an array access operation. */
     909                    prop->type, &mtitem);
     910                break;
     911        }
     912
     913        /*
     914         * Substitute type arguments in member titem.
     915         *
     916         * Since the CSI can be generic the actual type of the member
     917         * is obtained by substituting our type arguments into the
     918         * (generic) type of the member.
     919         */
     920
     921        stype_titem_to_tvv(stype, arg_ti, &tvv);
     922        tdata_item_subst(mtitem, tvv, rtitem);
     923}
     924
     925/** Type an array access operation.
     926 *
     927 * @param stype         Static typing object
     928 * @param access        Member access operation
     929 * @param arg_ti        Base type
     930 * @param rtitem        Place to store result type
     931 */
    771932static void stype_access_tarray(stype_t *stype, stree_access_t *access,
    772933    tdata_item_t *arg_ti, tdata_item_t **rtitem)
     
    783944}
    784945
    785 /** Type a call operation. */
     946/** Type a call operation.
     947 *
     948 * @param stype         Static typing object
     949 * @param call          Call operation
     950 * @param rtitem        Place to store result type
     951 */
    786952static void stype_call(stype_t *stype, stree_call_t *call,
    787953    tdata_item_t **rtitem)
    788954{
    789         list_node_t *farg_n;
    790         stree_proc_arg_t *farg;
     955        list_node_t *fargt_n;
    791956        tdata_item_t *farg_ti;
    792957        tdata_item_t *varg_ti;
     
    797962
    798963        tdata_item_t *fun_ti;
    799         stree_fun_t *fun;
    800         stree_symbol_t *fun_sym;
     964        tdata_fun_sig_t *tsig;
     965
     966        int cnt;
    801967
    802968#ifdef DEBUG_TYPE_TRACE
     
    807973
    808974        /* Check type item class */
    809 
    810975        fun_ti = call->fun->titem;
    811976        switch (fun_ti->tic) {
     977        case tic_tdeleg:
     978                tsig = stype_deleg_get_sig(stype, fun_ti->u.tdeleg);
     979                assert(tsig != NULL);
     980                break;
    812981        case tic_tfun:
    813                 /* The expected case */
     982                tsig = fun_ti->u.tfun->tsig;
    814983                break;
    815984        case tic_ignore:
     
    826995        }
    827996
    828         fun = fun_ti->u.tfun->fun;
    829         fun_sym = fun_to_symbol(fun);
    830 
    831997        /* Type and check the arguments. */
    832         farg_n = list_first(&fun->args);
     998        fargt_n = list_first(&tsig->arg_ti);
    833999        arg_n = list_first(&call->args);
    834         while (farg_n != NULL && arg_n != NULL) {
    835                 farg = list_node_data(farg_n, stree_proc_arg_t *);
     1000
     1001        cnt = 0;
     1002        while (fargt_n != NULL && arg_n != NULL) {
     1003                farg_ti = list_node_data(fargt_n, tdata_item_t *);
    8361004                arg = list_node_data(arg_n, stree_expr_t *);
    8371005                stype_expr(stype, arg);
    8381006
    8391007                /* XXX Because of overloaded bultin WriteLine */
    840                 if (farg->type == NULL) {
     1008                if (farg_ti == NULL) {
    8411009                        /* Skip the check */
    842                         farg_n = list_next(&fun->args, farg_n);
     1010                        fargt_n = list_next(&tsig->arg_ti, fargt_n);
    8431011                        arg_n = list_next(&call->args, arg_n);
    8441012                        continue;
    8451013                }
    8461014
    847                 /* XXX Memoize to avoid recomputing every time. */
    848                 run_texpr(stype->program, fun_sym->outer_csi, farg->type,
    849                     &farg_ti);
    850 
    8511015                /* Convert expression to type of formal argument. */
    8521016                carg = stype_convert(stype, arg, farg_ti);
     
    8551019                list_node_setdata(arg_n, carg);
    8561020
    857                 farg_n = list_next(&fun->args, farg_n);
     1021                fargt_n = list_next(&tsig->arg_ti, fargt_n);
    8581022                arg_n = list_next(&call->args, arg_n);
    8591023        }
    8601024
    8611025        /* Type and check variadic arguments. */
    862         if (fun->varg != NULL) {
    863                 /* XXX Memoize to avoid recomputing every time. */
    864                 run_texpr(stype->program, fun_sym->outer_csi, fun->varg->type,
    865                     &farg_ti);
     1026        if (tsig->varg_ti != NULL) {
     1027                /* Obtain type of packed argument. */
     1028                farg_ti = tsig->varg_ti;
    8661029
    8671030                /* Get array element type */
     
    8831046        }
    8841047
    885         if (farg_n != NULL) {
    886                 printf("Error: Too few arguments to function '");
    887                 symbol_print_fqn(fun_to_symbol(fun));
    888                 printf("'.\n");
     1048        if (fargt_n != NULL) {
     1049                printf("Error: Too few arguments to function.\n");
    8891050                stype_note_error(stype);
    8901051        }
    8911052
    8921053        if (arg_n != NULL) {
    893                 printf("Error: Too many arguments to function '");
    894                 symbol_print_fqn(fun_to_symbol(fun));
    895                 printf("'.\n");
    896                 stype_note_error(stype);
    897         }
    898 
    899         if (fun->rtype != NULL) {
    900                 /* XXX Memoize to avoid recomputing every time. */
    901                 run_texpr(stype->program, fun_sym->outer_csi, fun->rtype,
    902                     rtitem);
     1054                printf("Error: Too many arguments to function.\n");
     1055                stype_note_error(stype);
     1056        }
     1057
     1058        if (tsig->rtype != NULL) {
     1059                /* XXX Might be better to clone here. */
     1060                *rtitem = tsig->rtype;
    9031061        } else {
    9041062                *rtitem = NULL;
     
    9061064}
    9071065
    908 /** Type an indexing operation. */
     1066/** Type an indexing operation.
     1067 *
     1068 * @param stype         Static typing object
     1069 * @param index         Indexing operation
     1070 * @param rtitem        Place to store result type
     1071 */
    9091072static void stype_index(stype_t *stype, stree_index_t *index,
    9101073    tdata_item_t **rtitem)
     
    9391102                stype_index_tarray(stype, index, base_ti, rtitem);
    9401103                break;
     1104        case tic_tdeleg:
     1105                printf("Error: Indexing a delegate.\n");
     1106                stype_note_error(stype);
     1107                *rtitem = stype_recovery_titem(stype);
     1108                break;
    9411109        case tic_tfun:
    9421110                printf("Error: Indexing a function.\n");
     
    9441112                *rtitem = stype_recovery_titem(stype);
    9451113                break;
     1114        case tic_tvref:
     1115                /* Cannot allow this without some constraint. */
     1116                printf("Error: Indexing generic data.\n");
     1117                *rtitem = stype_recovery_titem(stype);
     1118                break;
    9461119        case tic_ignore:
    9471120                *rtitem = stype_recovery_titem(stype);
     
    9501123}
    9511124
    952 /** Type a primitive indexing operation. */
     1125/** Type a primitive indexing operation.
     1126 *
     1127 * @param stype         Static typing object
     1128 * @param index         Indexing operation
     1129 * @param base_ti       Base type (primitive being indexed)
     1130 * @param rtitem        Place to store result type
     1131 */
    9531132static void stype_index_tprimitive(stype_t *stype, stree_index_t *index,
    9541133    tdata_item_t *base_ti, tdata_item_t **rtitem)
     
    9771156}
    9781157
    979 /** Type an object indexing operation. */
     1158/** Type an object indexing operation.
     1159 *
     1160 * @param stype         Static typing object
     1161 * @param index         Indexing operation
     1162 * @param base_ti       Base type (object being indexed)
     1163 * @param rtitem        Place to store result type
     1164 */
    9801165static void stype_index_tobject(stype_t *stype, stree_index_t *index,
    9811166    tdata_item_t *base_ti, tdata_item_t **rtitem)
     
    9851170        stree_prop_t *idx;
    9861171        stree_ident_t *idx_ident;
     1172        tdata_item_t *mtitem;
     1173        tdata_tvv_t *tvv;
    9871174
    9881175        (void) index;
     
    10151202
    10161203        /* XXX Memoize to avoid recomputing every time. */
    1017         run_texpr(stype->program, idx_sym->outer_csi, idx->type, rtitem);
    1018 }
    1019 
    1020 /** Type an array indexing operation. */
     1204        run_texpr(stype->program, idx_sym->outer_csi, idx->type, &mtitem);
     1205
     1206        /*
     1207         * Substitute type arguments in member titem.
     1208         *
     1209         * Since the CSI can be generic the actual type of the member
     1210         * is obtained by substituting our type arguments into the
     1211         * (generic) type of the member.
     1212         */
     1213
     1214        stype_titem_to_tvv(stype, base_ti, &tvv);
     1215        tdata_item_subst(mtitem, tvv, rtitem);
     1216}
     1217
     1218/** Type an array indexing operation.
     1219 *
     1220 * @param stype         Static typing object
     1221 * @param index         Indexing operation
     1222 * @param base_ti       Base type (array being indexed)
     1223 * @param rtitem        Place to store result type
     1224 */
    10211225static void stype_index_tarray(stype_t *stype, stree_index_t *index,
    10221226    tdata_item_t *base_ti, tdata_item_t **rtitem)
     
    10581262}
    10591263
    1060 /** Type an assignment. */
     1264/** Type an assignment.
     1265 *
     1266 * @param stype         Static typing object
     1267 * @param assign        Assignment operation
     1268 * @param rtitem        Place to store result type
     1269 */
    10611270static void stype_assign(stype_t *stype, stree_assign_t *assign,
    10621271    tdata_item_t **rtitem)
     
    10771286}
    10781287
    1079 /** Type @c as conversion. */
     1288/** Type @c as conversion.
     1289 *
     1290 * @param stype         Static typing object
     1291 * @param as_op         @c as conversion operation
     1292 * @param rtitem        Place to store result type
     1293 */
    10801294static void stype_as(stype_t *stype, stree_as_t *as_op, tdata_item_t **rtitem)
    10811295{
     
    11001314        *rtitem = titem;
    11011315}
     1316
     1317/** Type boxing operation.
     1318 *
     1319 * While there is no boxing operation on the first typing pass, we do want
     1320 * to allow potential re-evaluation (with same results).
     1321 *
     1322 * @param stype         Static typing object
     1323 * @param box           Boxing operation
     1324 * @param rtitem        Place to store result type
     1325 */
     1326static void stype_box(stype_t *stype, stree_box_t *box, tdata_item_t **rtitem)
     1327{
     1328        tdata_item_t *ptitem, *btitem;
     1329        tdata_object_t *tobject;
     1330        stree_symbol_t *csi_sym;
     1331        builtin_t *bi;
     1332
     1333#ifdef DEBUG_TYPE_TRACE
     1334        printf("Evaluate type of boxing operation.\n");
     1335#endif
     1336        bi = stype->program->builtin;
     1337
     1338        stype_expr(stype, box->arg);
     1339        ptitem = box->arg->titem;
     1340
     1341        /* Make compiler happy. */
     1342        csi_sym = NULL;
     1343
     1344        assert(ptitem->tic == tic_tprimitive);
     1345        switch (ptitem->u.tprimitive->tpc) {
     1346        case tpc_bool: csi_sym = bi->boxed_bool; break;
     1347        case tpc_char: csi_sym = bi->boxed_char; break;
     1348        case tpc_int: csi_sym = bi->boxed_int; break;
     1349        case tpc_nil: assert(b_false);
     1350        case tpc_string: csi_sym = bi->boxed_string; break;
     1351        case tpc_resource: assert(b_false);
     1352        }
     1353
     1354        btitem = tdata_item_new(tic_tobject);
     1355        tobject = tdata_object_new();
     1356
     1357        btitem->u.tobject = tobject;
     1358        tobject->static_ref = b_false;
     1359        tobject->csi = symbol_to_csi(csi_sym);
     1360        assert(tobject->csi != NULL);
     1361        list_init(&tobject->targs);
     1362
     1363        *rtitem = btitem;
     1364}
  • uspace/app/sbi/src/symbol.c

    r80badbe r883fedc  
    4444static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol);
    4545
    46 /** Lookup symbol in CSI using a type expression. */
     46/** Lookup symbol in CSI using a type expression.
     47 *
     48 * XXX This should be removed in favor of full type expression evaluation
     49 * (run_texpr). This cannot work properly with generics.
     50 *
     51 * @param prog          Program
     52 * @param scope         CSI used as base for relative references
     53 * @param texpr         Type expression
     54 *
     55 * @return              Symbol referenced by type expression or @c NULL
     56 *                      if not found
     57 */
    4758stree_symbol_t *symbol_xlookup_in_csi(stree_program_t *prog,
    4859    stree_csi_t *scope, stree_texpr_t *texpr)
     
    7788/** Lookup symbol reference in CSI.
    7889 *
    79  * @param prog  Program to look in.
    80  * @param scope CSI in @a prog which is the base for references.
    81  * @param name  Identifier of the symbol.
    82  *
    83  * @return      Symbol or @c NULL if symbol not found.
     90 * @param prog  Program to look in
     91 * @param scope CSI in @a prog which is the base for references
     92 * @param name  Identifier of the symbol
     93 *
     94 * @return      Symbol or @c NULL if symbol not found
    8495 */
    8596stree_symbol_t *symbol_lookup_in_csi(stree_program_t *prog, stree_csi_t *scope,
     
    107118 * Look for symbol in definition of a CSI and its ancestors. (But not
    108119 * in lexically enclosing CSI.)
     120 *
     121 * @param prog  Program to look in
     122 * @param scope CSI in which to look
     123 * @param name  Identifier of the symbol
     124 *
     125 * @return      Symbol or @c NULL if symbol not found.
    109126 */
    110127stree_symbol_t *symbol_search_csi(stree_program_t *prog,
     
    125142        while (node != NULL) {
    126143                csimbr = list_node_data(node, stree_csimbr_t *);
     144
     145                /* Keep compiler happy. */
     146                mbr_name = NULL;
     147
    127148                switch (csimbr->cc) {
    128149                case csimbr_csi: mbr_name = csimbr->u.csi->name; break;
     150                case csimbr_deleg: mbr_name = csimbr->u.deleg->name; break;
    129151                case csimbr_fun: mbr_name = csimbr->u.fun->name; break;
    130152                case csimbr_var: mbr_name = csimbr->u.var->name; break;
    131153                case csimbr_prop: mbr_name = csimbr->u.prop->name; break;
    132                 default: assert(b_false);
    133154                }
    134155
     
    138159                        case csimbr_csi:
    139160                                symbol = csi_to_symbol(csimbr->u.csi);
     161                                break;
     162                        case csimbr_deleg:
     163                                symbol = deleg_to_symbol(csimbr->u.deleg);
    140164                                break;
    141165                        case csimbr_fun:
     
    170194}
    171195
     196/** Look for symbol in global scope.
     197 *
     198 * @param prog  Program to look in
     199 * @param name  Identifier of the symbol
     200 *
     201 * @return      Symbol or @c NULL if symbol not found.
     202 */
    172203static stree_symbol_t *symbol_search_global(stree_program_t *prog,
    173204    stree_ident_t *name)
     
    197228}
    198229
    199 /** Find entry point. */
     230/** Find entry point.
     231 *
     232 * Perform a walk of all CSIs and look for a function with the name @a name.
     233 *
     234 * @param prog  Program to look in
     235 * @param name  Name of entry point
     236 *
     237 * @return      Symbol or @c NULL if symbol not found.
     238 */
    200239stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name)
    201240{
     
    225264}
    226265
     266/** Find entry point under CSI.
     267 *
     268 * Internal part of symbol_find_epoint() that recursively walks CSIs.
     269 *
     270 * @param prog  Program to look in
     271 * @param name  Name of entry point
     272 *
     273 * @return      Symbol or @c NULL if symbol not found.
     274 */
    227275static stree_symbol_t *symbol_find_epoint_rec(stree_program_t *prog,
    228276    stree_ident_t *name, stree_csi_t *csi)
     
    267315}
    268316
     317/*
     318 * The notion of symbol is designed as a common base class for several
     319 * types of declarations with global and CSI scope. Here we simulate
     320 * conversion from this base class (symbol) to derived classes (CSI,
     321 * fun, ..) and vice versa.
     322 */
     323
     324/** Convert symbol to delegate (base to derived).
     325 *
     326 * @param symbol        Symbol
     327 * @return              Delegate or @c NULL if symbol is not a delegate
     328 */
     329stree_deleg_t *symbol_to_deleg(stree_symbol_t *symbol)
     330{
     331        if (symbol->sc != sc_deleg)
     332                return NULL;
     333
     334        return symbol->u.deleg;
     335}
     336
     337/** Convert delegate to symbol (derived to base).
     338 *
     339 * @param deleg         Delegate
     340 * @return              Symbol
     341 */
     342stree_symbol_t *deleg_to_symbol(stree_deleg_t *deleg)
     343{
     344        assert(deleg->symbol);
     345        return deleg->symbol;
     346}
     347
     348/** Convert symbol to CSI (base to derived).
     349 *
     350 * @param symbol        Symbol
     351 * @return              CSI or @c NULL if symbol is not a CSI
     352 */
    269353stree_csi_t *symbol_to_csi(stree_symbol_t *symbol)
    270354{
     
    275359}
    276360
     361/** Convert CSI to symbol (derived to base).
     362 *
     363 * @param csi           CSI
     364 * @return              Symbol
     365 */
    277366stree_symbol_t *csi_to_symbol(stree_csi_t *csi)
    278367{
     
    281370}
    282371
     372/** Convert symbol to function (base to derived).
     373 *
     374 * @param symbol        Symbol
     375 * @return              Function or @c NULL if symbol is not a function
     376 */
    283377stree_fun_t *symbol_to_fun(stree_symbol_t *symbol)
    284378{
     
    289383}
    290384
     385/** Convert function to symbol (derived to base).
     386 *
     387 * @param fun           Function
     388 * @return              Symbol
     389 */
    291390stree_symbol_t *fun_to_symbol(stree_fun_t *fun)
    292391{
     
    295394}
    296395
     396/** Convert symbol to member variable (base to derived).
     397 *
     398 * @param symbol        Symbol
     399 * @return              Variable or @c NULL if symbol is not a member variable
     400 */
    297401stree_var_t *symbol_to_var(stree_symbol_t *symbol)
    298402{
     
    303407}
    304408
     409/** Convert variable to symbol (derived to base).
     410 *
     411 * @param fun           Variable
     412 * @return              Symbol
     413 */
    305414stree_symbol_t *var_to_symbol(stree_var_t *var)
    306415{
     
    309418}
    310419
     420/** Convert symbol to property (base to derived).
     421 *
     422 * @param symbol        Symbol
     423 * @return              Property or @c NULL if symbol is not a property
     424 */
    311425stree_prop_t *symbol_to_prop(stree_symbol_t *symbol)
    312426{
     
    317431}
    318432
     433/** Convert property to symbol (derived to base).
     434 *
     435 * @param fun           Property
     436 * @return              Symbol
     437 */
    319438stree_symbol_t *prop_to_symbol(stree_prop_t *prop)
    320439{
     
    323442}
    324443
    325 /** Print fully qualified name of symbol. */
     444/** Print fully qualified name of symbol.
     445 *
     446 * @param symbol        Symbol
     447 */
    326448void symbol_print_fqn(stree_symbol_t *symbol)
    327449{
     
    339461}
    340462
     463/** Return symbol identifier.
     464 *
     465 * @param symbol        Symbol
     466 * @return              Symbol identifier
     467 */
    341468static stree_ident_t *symbol_get_ident(stree_symbol_t *symbol)
    342469{
     
    345472        switch (symbol->sc) {
    346473        case sc_csi: ident = symbol->u.csi->name; break;
     474        case sc_deleg: ident = symbol->u.deleg->name; break;
    347475        case sc_fun: ident = symbol->u.fun->name; break;
    348476        case sc_var: ident = symbol->u.var->name; break;
  • uspace/app/sbi/src/symbol.h

    r80badbe r883fedc  
    4040stree_symbol_t *symbol_find_epoint(stree_program_t *prog, stree_ident_t *name);
    4141
     42stree_deleg_t *symbol_to_deleg(stree_symbol_t *symbol);
     43stree_symbol_t *deleg_to_symbol(stree_deleg_t *deleg);
    4244stree_csi_t *symbol_to_csi(stree_symbol_t *symbol);
    4345stree_symbol_t *csi_to_symbol(stree_csi_t *csi);
  • uspace/app/sbi/src/tdata.c

    r80badbe r883fedc  
    3131#include <stdlib.h>
    3232#include <assert.h>
     33#include "intmap.h"
    3334#include "list.h"
    3435#include "mytypes.h"
    3536#include "stree.h"
     37#include "strtab.h"
    3638#include "symbol.h"
    3739
    3840#include "tdata.h"
     41
     42static void tdata_item_subst_tprimitive(tdata_primitive_t *torig,
     43    tdata_tvv_t *tvv, tdata_item_t **res);
     44static void tdata_item_subst_tobject(tdata_object_t *torig, tdata_tvv_t *tvv,
     45    tdata_item_t **res);
     46static void tdata_item_subst_tarray(tdata_array_t *torig, tdata_tvv_t *tvv,
     47    tdata_item_t **res);
     48static void tdata_item_subst_tdeleg(tdata_deleg_t *torig,
     49    tdata_tvv_t *tvv, tdata_item_t **res);
     50static void tdata_item_subst_tfun(tdata_fun_t *torig,
     51    tdata_tvv_t *tvv, tdata_item_t **res);
     52static void tdata_item_subst_tvref(tdata_vref_t *tvref, tdata_tvv_t *tvv,
     53    tdata_item_t **res);
     54
     55static void tdata_item_subst_fun_sig(tdata_fun_sig_t *torig, tdata_tvv_t *tvv,
     56    tdata_fun_sig_t **res);
    3957
    4058static void tdata_tprimitive_print(tdata_primitive_t *tprimitive);
    4159static void tdata_tobject_print(tdata_object_t *tobject);
    4260static void tdata_tarray_print(tdata_array_t *tarray);
     61static void tdata_tdeleg_print(tdata_deleg_t *tdeleg);
    4362static void tdata_tfun_print(tdata_fun_t *tfun);
    44 
    45 /** Determine if CSI @a a is derived from CSI described by type item @a tb. */
     63static void tdata_tvref_print(tdata_vref_t *tvref);
     64
     65/** Determine if CSI @a a is derived from CSI described by type item @a tb.
     66 *
     67 * XXX This won't work with generics.
     68 *
     69 * @param a     Potential derived CSI.
     70 * @param tb    Type of potentail base CSI.
     71 */
    4672bool_t tdata_is_csi_derived_from_ti(stree_csi_t *a, tdata_item_t *tb)
    4773{
     
    6389 * Determine if CSI described by type item @a a is derived from CSI described
    6490 * by type item @a tb.
     91 *
     92 * XXX This is somewhat complementary to stype_convert(). It is used for
     93 * the explicit @c as conversion. It should only work for objects and only
     94 * allow conversion from base to derived types. We might want to scrap this
     95 * for a version specific to @c as. The current code does not work with
     96 * generics.
     97 *
     98 * @param a     Potential derived CSI.
     99 * @param tb    Type of potentail base CSI.
    65100 */
    66101bool_t tdata_is_ti_derived_from_ti(tdata_item_t *ta, tdata_item_t *tb)
     
    80115}
    81116
    82 /** Determine if two type items are equal (i.e. describe the same type). */
     117/** Determine if two type items are equal (i.e. describe the same type).
     118 *
     119 * Needed to check compatibility of type arguments in which a parametrized
     120 * type is not monotonous.
     121 *
     122 * @param a     Type item
     123 * @param b     Type item
     124 * @return      @c b_true if equal, @c b_false if not.
     125 */
    83126bool_t tdata_item_equal(tdata_item_t *a, tdata_item_t *b)
    84127{
     
    114157                return tdata_item_equal(a->u.tarray->base_ti,
    115158                    b->u.tarray->base_ti);
     159        case tic_tvref:
     160                /* Check if both refer to the same type argument. */
     161                return (a->u.tvref->targ == b->u.tvref->targ);
    116162        default:
    117163                printf("Warning: Unimplemented: Compare types '");
     
    124170}
    125171
    126 /** Print type item. */
     172/** Substitute type variables in a type item.
     173 *
     174 * This is the second part of generic type application. In the first part
     175 * obtained a TVV using stype_titem_to_tvv() and in this second part we
     176 * actually substitute type variables in a type item for their values.
     177 * @a tvv must contain all variables referenced in @a ti.
     178 *
     179 * @param ti    Type item to substitute into.
     180 * @param tvv   Type variable valuation (values of type variables).
     181 * @param res   Place to store pointer to new type item.
     182 */
     183void tdata_item_subst(tdata_item_t *ti, tdata_tvv_t *tvv, tdata_item_t **res)
     184{
     185        switch (ti->tic) {
     186        case tic_tprimitive:
     187                tdata_item_subst_tprimitive(ti->u.tprimitive, tvv, res);
     188                break;
     189        case tic_tobject:
     190                tdata_item_subst_tobject(ti->u.tobject, tvv, res);
     191                break;
     192        case tic_tarray:
     193                tdata_item_subst_tarray(ti->u.tarray, tvv, res);
     194                break;
     195        case tic_tdeleg:
     196                tdata_item_subst_tdeleg(ti->u.tdeleg, tvv, res);
     197                break;
     198        case tic_tfun:
     199                tdata_item_subst_tfun(ti->u.tfun, tvv, res);
     200                break;
     201        case tic_tvref:
     202                tdata_item_subst_tvref(ti->u.tvref, tvv, res);
     203                break;
     204        case tic_ignore:
     205                *res = tdata_item_new(tic_ignore);
     206        }
     207}
     208
     209/** Substitute type variables in a primitive type item.
     210 *
     211 * @param torig Type item to substitute into.
     212 * @param tvv   Type variable valuation (values of type variables).
     213 * @param res   Place to store pointer to new type item.
     214 */
     215static void tdata_item_subst_tprimitive(tdata_primitive_t *torig,
     216    tdata_tvv_t *tvv, tdata_item_t **res)
     217{
     218        tdata_primitive_t *tnew;
     219
     220        (void) tvv;
     221
     222        /* Plain copy */
     223        tnew = tdata_primitive_new(torig->tpc);
     224        *res = tdata_item_new(tic_tprimitive);
     225        (*res)->u.tprimitive = tnew;
     226}
     227
     228/** Substitute type variables in an object type item.
     229 *
     230 * @param torig Type item to substitute into.
     231 * @param tvv   Type variable valuation (values of type variables).
     232 * @param res   Place to store pointer to new type item.
     233 */
     234static void tdata_item_subst_tobject(tdata_object_t *torig, tdata_tvv_t *tvv,
     235    tdata_item_t **res)
     236{
     237        tdata_object_t *tnew;
     238        list_node_t *targ_n;
     239        tdata_item_t *targ;
     240        tdata_item_t *new_targ;
     241
     242        /* Copy static ref flag and base CSI. */
     243        tnew = tdata_object_new();
     244        tnew->static_ref = torig->static_ref;
     245        tnew->csi = torig->csi;
     246        list_init(&tnew->targs);
     247
     248        /* Substitute arguments */
     249        targ_n = list_first(&torig->targs);
     250        while (targ_n != NULL) {
     251                targ = list_node_data(targ_n, tdata_item_t *);
     252                tdata_item_subst(targ, tvv, &new_targ);
     253                list_append(&tnew->targs, new_targ);
     254
     255                targ_n = list_next(&torig->targs, targ_n);
     256        }
     257
     258        *res = tdata_item_new(tic_tobject);
     259        (*res)->u.tobject = tnew;
     260}
     261
     262/** Substitute type variables in an array type item.
     263 *
     264 * @param torig Type item to substitute into.
     265 * @param tvv   Type variable valuation (values of type variables).
     266 * @param res   Place to store pointer to new type item.
     267 */
     268static void tdata_item_subst_tarray(tdata_array_t *torig, tdata_tvv_t *tvv,
     269    tdata_item_t **res)
     270{
     271        tdata_array_t *tnew;
     272        list_node_t *ext_n;
     273        stree_expr_t *extent;
     274
     275        tnew = tdata_array_new();
     276
     277        /* Substitute base type */
     278        tdata_item_subst(torig->base_ti, tvv, &tnew->base_ti);
     279
     280        /* Copy rank and extents */
     281        tnew->rank = torig->rank;
     282        list_init(&tnew->extents);
     283
     284        ext_n = list_first(&torig->extents);
     285        while (ext_n != NULL) {
     286                extent = list_node_data(ext_n, stree_expr_t *);
     287                list_append(&tnew->extents, extent);
     288
     289                ext_n = list_next(&tnew->extents, ext_n);
     290        }
     291
     292        *res = tdata_item_new(tic_tarray);
     293        (*res)->u.tarray = tnew;
     294}
     295
     296/** Substitute type variables in a delegate type item.
     297 *
     298 * @param torig Type item to substitute into.
     299 * @param tvv   Type variable valuation (values of type variables).
     300 * @param res   Place to store pointer to new type item.
     301 */
     302static void tdata_item_subst_tdeleg(tdata_deleg_t *torig, tdata_tvv_t *tvv,
     303    tdata_item_t **res)
     304{
     305        tdata_deleg_t *tnew;
     306
     307        tnew = tdata_deleg_new();
     308        tnew->deleg = torig->deleg;
     309        tdata_item_subst_fun_sig(torig->tsig, tvv, &tnew->tsig);
     310
     311        *res = tdata_item_new(tic_tdeleg);
     312        (*res)->u.tdeleg = tnew;
     313}
     314
     315/** Substitute type variables in a functional type item.
     316 *
     317 * @param torig Type item to substitute into.
     318 * @param tvv   Type variable valuation (values of type variables).
     319 * @param res   Place to store pointer to new type item.
     320 */
     321static void tdata_item_subst_tfun(tdata_fun_t *torig, tdata_tvv_t *tvv,
     322    tdata_item_t **res)
     323{
     324        tdata_fun_t *tnew;
     325
     326        tnew = tdata_fun_new();
     327        tdata_item_subst_fun_sig(torig->tsig, tvv, &tnew->tsig);
     328
     329        *res = tdata_item_new(tic_tfun);
     330        (*res)->u.tfun = tnew;
     331}
     332
     333/** Substitute type variables in a type-variable reference item.
     334 *
     335 * @param torig Type item to substitute into.
     336 * @param tvv   Type variable valuation (values of type variables).
     337 * @param res   Place to store pointer to new type item.
     338 */
     339static void tdata_item_subst_tvref(tdata_vref_t *tvref, tdata_tvv_t *tvv,
     340    tdata_item_t **res)
     341{
     342        tdata_item_t *ti_new;
     343
     344        ti_new = tdata_tvv_get_val(tvv, tvref->targ->name->sid);
     345        assert(ti_new != NULL);
     346
     347        /* XXX Might be better to clone here. */
     348        *res = ti_new;
     349}
     350
     351/** Substitute type variables in a function signature type fragment.
     352 *
     353 * @param torig Type item to substitute into.
     354 * @param tvv   Type variable valuation (values of type variables).
     355 * @param res   Place to store pointer to new type item.
     356 */
     357static void tdata_item_subst_fun_sig(tdata_fun_sig_t *torig, tdata_tvv_t *tvv,
     358    tdata_fun_sig_t **res)
     359{
     360        tdata_fun_sig_t *tnew;
     361        list_node_t *arg_n;
     362        tdata_item_t *arg_ti;
     363        tdata_item_t *narg_ti;
     364
     365        tnew = tdata_fun_sig_new();
     366
     367        /* Substitute type of each argument */
     368        list_init(&tnew->arg_ti);
     369        arg_n = list_first(&torig->arg_ti);
     370        while (arg_n != NULL) {
     371                arg_ti = list_node_data(arg_n, tdata_item_t *);
     372
     373                /* XXX Because of overloaded Builtin.WriteLine */
     374                if (arg_ti == NULL)
     375                        narg_ti = NULL;
     376                else
     377                        tdata_item_subst(arg_ti, tvv, &narg_ti);
     378
     379                list_append(&tnew->arg_ti, narg_ti);
     380
     381                arg_n = list_next(&torig->arg_ti, arg_n);
     382        }
     383
     384        /* Substitute type of variadic argument */
     385        if (torig->varg_ti != NULL)
     386                tdata_item_subst(torig->varg_ti, tvv, &tnew->varg_ti);
     387
     388        /* Substitute return type */
     389        if (torig->rtype != NULL)
     390                tdata_item_subst(torig->rtype, tvv, &tnew->rtype);
     391
     392        *res = tnew;
     393}
     394
     395
     396/** Print type item.
     397 *
     398 * @param titem Type item
     399 */
    127400void tdata_item_print(tdata_item_t *titem)
    128401{
     
    142415                tdata_tarray_print(titem->u.tarray);
    143416                break;
     417        case tic_tdeleg:
     418                tdata_tdeleg_print(titem->u.tdeleg);
     419                break;
    144420        case tic_tfun:
    145421                tdata_tfun_print(titem->u.tfun);
    146422                break;
     423        case tic_tvref:
     424                tdata_tvref_print(titem->u.tvref);
     425                break;
    147426        case tic_ignore:
    148427                printf("ignore");
     
    151430}
    152431
     432/** Print primitive type item.
     433 *
     434 * @param tprimitive    Primitive type item
     435 */
    153436static void tdata_tprimitive_print(tdata_primitive_t *tprimitive)
    154437{
     
    163446}
    164447
     448/** Print object type item.
     449 *
     450 * @param tobject       Object type item
     451 */
    165452static void tdata_tobject_print(tdata_object_t *tobject)
    166453{
     
    182469}
    183470
     471/** Print array type item.
     472 *
     473 * @param tarray        Array type item
     474 */
    184475static void tdata_tarray_print(tdata_array_t *tarray)
    185476{
     
    194485}
    195486
     487/** Print delegate type item.
     488 *
     489 * @param tdeleg        Delegate type item
     490 */
     491static void tdata_tdeleg_print(tdata_deleg_t *tdeleg)
     492{
     493        stree_symbol_t *deleg_sym;
     494
     495        deleg_sym = deleg_to_symbol(tdeleg->deleg);
     496        symbol_print_fqn(deleg_sym);
     497}
     498
     499/** Print function type item.
     500 *
     501 * @param tfun          Function type item
     502 */
    196503static void tdata_tfun_print(tdata_fun_t *tfun)
    197504{
    198         (void) tfun;
    199         printf("unimplemented(fun)");
    200 }
    201 
     505        list_node_t *arg_n;
     506        tdata_item_t *arg_ti;
     507        bool_t first;
     508
     509        printf("fun(");
     510
     511        arg_n = list_first(&tfun->tsig->arg_ti);
     512        first = b_true;
     513        while (arg_n != NULL) {
     514                if (first == b_false)
     515                        printf("; ");
     516                else
     517                        first = b_false;
     518
     519                arg_ti = list_node_data(arg_n, tdata_item_t *);
     520                tdata_item_print(arg_ti);
     521
     522                arg_n = list_next(&tfun->tsig->arg_ti, arg_n);
     523        }
     524
     525        printf(") : ");
     526        tdata_item_print(tfun->tsig->rtype);
     527}
     528
     529/** Print type variable reference type item.
     530 *
     531 * @param tvref         Type variable reference type item
     532 */
     533static void tdata_tvref_print(tdata_vref_t *tvref)
     534{
     535        printf("%s", strtab_get_str(tvref->targ->name->sid));
     536}
     537
     538/** Allocate new type item.
     539 *
     540 * @param tic   Type item class
     541 * @return      New type item
     542 */
    202543tdata_item_t *tdata_item_new(titem_class_t tic)
    203544{
     
    214555}
    215556
     557/** Allocate new array type item.
     558 *
     559 * @return      New array type item
     560 */
    216561tdata_array_t *tdata_array_new(void)
    217562{
     
    227572}
    228573
     574/** Allocate new object type item.
     575 *
     576 * @return      New object type item
     577 */
    229578tdata_object_t *tdata_object_new(void)
    230579{
     
    240589}
    241590
     591/** Allocate new primitive type item.
     592 *
     593 * @return      New primitive type item
     594 */
    242595tdata_primitive_t *tdata_primitive_new(tprimitive_class_t tpc)
    243596{
     
    254607}
    255608
     609/** Allocate new delegate type item.
     610 *
     611 * @return      New function type item
     612 */
     613tdata_deleg_t *tdata_deleg_new(void)
     614{
     615        tdata_deleg_t *tdeleg;
     616
     617        tdeleg = calloc(1, sizeof(tdata_deleg_t));
     618        if (tdeleg == NULL) {
     619                printf("Memory allocation failed.\n");
     620                exit(1);
     621        }
     622
     623        return tdeleg;
     624}
     625
     626/** Allocate new functional type item.
     627 *
     628 * @return      New function type item
     629 */