Exemple #1
0
/* Create an entry for the variable NAME with TYPE and value VAL,
   in the symbol table.  */
int
boot_script_set_variable (const char *name, int type, int val)
{
  struct sym *sym = sym_enter (name);

  if (sym)
    {
      sym->type = type;
      sym->val = val;
    }
  return sym ? 0 : 1;
}
Exemple #2
0
static void traverse_decl(ast_decl_t decl)
{
    switch (decl->kind)
    {
        case AST_FUNCS_DECL: {
            list_t p = decl->u.funcs;
            for (; p; p = p->next)
            {
                ast_func_t func = p->data;
                list_t q;

                _depth++;
                sym_begin_scope(_env);
                for (q = func->params; q; q = q->next)
                {
                    ast_field_t field = q->data;
                    sym_enter(_env,
                              field->name,
                              escape_entry(_depth, &field->escape));
                }
                traverse_expr(func->body);
                sym_end_scope(_env);
                _depth--;
            }
            break;
        }

        case AST_TYPES_DECL:
            break;

        case AST_VAR_DECL:
            sym_enter(_env,
                      decl->u.var.var,
                      escape_entry(_depth, &decl->u.var.escape));
            traverse_expr(decl->u.var.init);
            break;
    }
}
Exemple #3
0
/* Define the function NAME, which will return type RET_TYPE.  */
int
boot_script_define_function (const char *name, int ret_type,
			     int (*func) (const struct cmd *cmd, int *val))
{
  struct sym *sym = sym_enter (name);

  if (sym)
    {
      sym->type = VAL_FUNC;
      sym->val = (int) func;
      sym->ret_type = ret_type;
      sym->run_on_exec = ret_type == VAL_NONE;
    }
  return sym ? 0 : 1;
}
Exemple #4
0
static t_stat symset_cmd(int32 arg, CONST char* buf)
{
    const char *name,*vstr;
    char gbuf[2*CBUFSIZE];
    t_addr val;

    gbuf[sizeof(gbuf)-1] = '\0';
    strncpy(gbuf, buf, sizeof(gbuf)-1);
    if ((name = strtok(gbuf, "= ")) == 0) return SCPE_2FARG;
    if ((vstr = strtok(NULL, " \t\n")) == 0) return SCPE_2FARG;
    val = strtol(vstr, 0, 16);
    if (!sym_enter(name, val))
        printf("Name or value already exists\n");
    return SCPE_OK;
}
Exemple #5
0
static void traverse_expr(ast_expr_t expr)
{
    list_t p;

    switch (expr->kind)
    {
        case AST_NIL_EXPR:
            break;

        case AST_VAR_EXPR:
            traverse_var(expr->u.var);
            break;

        case AST_NUM_EXPR:
        case AST_STRING_EXPR:
            break;

        case AST_CALL_EXPR:
            for (p = expr->u.call.args; p; p = p->next)
                traverse_expr(p->data);
            break;

        case AST_OP_EXPR:
            traverse_expr(expr->u.op.left);
            traverse_expr(expr->u.op.right);
            break;

        case AST_RECORD_EXPR:
            for (p = expr->u.record.efields; p; p = p->next)
                traverse_expr(((ast_efield_t) p->data)->expr);
            break;

        case AST_ARRAY_EXPR:
            traverse_expr(expr->u.array.size);
            traverse_expr(expr->u.array.init);
            break;

        case AST_SEQ_EXPR:
            for (p = expr->u.seq; p; p = p->next)
                traverse_expr(p->data);
            break;

        case AST_IF_EXPR:
            traverse_expr(expr->u.if_.cond);
            traverse_expr(expr->u.if_.then);
            if (expr->u.if_.else_)
                traverse_expr(expr->u.if_.else_);
            break;

        case AST_WHILE_EXPR:
            traverse_expr(expr->u.while_.cond);
            traverse_expr(expr->u.while_.body);
            break;

        case AST_FOR_EXPR:
            traverse_expr(expr->u.for_.lo);
            traverse_expr(expr->u.for_.hi);
            sym_begin_scope(_env);
            sym_enter(_env,
                      expr->u.for_.var,
                      escape_entry(_depth, &expr->u.for_.escape));
            traverse_expr(expr->u.for_.body);
            sym_end_scope(_env);
            break;

        case AST_BREAK_EXPR:
            break;

        case AST_LET_EXPR:
            sym_begin_scope(_env);
            for (p = expr->u.let.decls; p; p = p->next)
                traverse_decl(p->data);
            traverse_expr(expr->u.let.body);
            sym_end_scope(_env);
            break;

        case AST_ASSIGN_EXPR:
            traverse_var(expr->u.assign.var);
            traverse_expr(expr->u.assign.expr);
            break;
    }
}
Exemple #6
0
/* Parse the command line CMDLINE.  */
int
boot_script_parse_line (void *hook, char *cmdline)
{
  char *p, *q;
  int error;
  struct cmd *cmd;
  struct arg *arg;

  /* Extract command name.  Ignore line if it lacks a command.  */
  for (p = cmdline; *p == ' ' || *p == '\t'; p++)
    ;
  if (*p == '#')
    /* Ignore comment line.  */
    return 0;

#if 0
  if (*p && *p != ' ' && *p != '\t' && *p != '\n')
    {
      printf ("(bootstrap): %s\n", cmdline);
    }
#endif

  for (q = p; *q && *q != ' ' && *q != '\t' && *q != '\n'; q++)
    ;
  if (p == q)
      return 0;

  *q = '\0';

  /* Allocate a command structure.  */
  cmd = boot_script_malloc (sizeof (struct cmd));
  if (! cmd)
    return BOOT_SCRIPT_NOMEM;
  memset (cmd, 0, sizeof (struct cmd));
  cmd->hook = hook;
  cmd->path = p;
  p = q + 1;

  for (arg = 0;;)
    {
      if (! arg)
	{
	  /* Skip whitespace.  */
	  while (*p == ' ' || *p == '\t')
	    p++;

	  /* End of command line.  */
	  if (! *p || *p == '\n')
	    {
	      /* Add command to list.  */
	      if (add_list (cmd, (void ***) &cmds,
			    &cmds_alloc, &cmds_index, 10))
		{
		  error = BOOT_SCRIPT_NOMEM;
		  goto bad;
		}
	      return 0;
	    }
	}

      /* Look for a symbol.  */
      if (arg || (*p == '$' && (*(p + 1) == '{' || *(p + 1) == '(')))
	{
	  char end_char = (*(p + 1) == '{') ? '}' : ')';
	  struct sym *sym = 0;

	  for (p += 2;;)
	    {
	      char c;
	      int i, val, type;
	      struct sym *s;

	      /* Parse symbol name.  */
	      for (q = p; *q && *q != '\n' && *q != end_char && *q != '='; q++)
		;
	      if (p == q || ! *q || *q == '\n'
		  || (end_char == '}' && *q != '}'))
		{
		  error = BOOT_SCRIPT_SYNTAX_ERROR;
		  goto bad;
		}
	      c = *q;
	      *q = '\0';

	      /* See if this is a builtin symbol.  */
	      for (i = 0; i < NUM_BUILTIN; i++)
		if (! strcmp (p, builtin_symbols[i].name))
		  break;

	      if (i < NUM_BUILTIN)
		s = &builtin_symbols[i];
	      else
		{
		  /* Look up symbol in symbol table.
		     If no entry exists, create one.  */
		  s = sym_lookup (p);
		  if (! s)
		    {
		      s = sym_enter (p);
		      if (! s)
			{
			  error = BOOT_SCRIPT_NOMEM;
			  goto bad;
			}
		    }
		}

	      /* Only values are allowed in ${...} constructs.  */
	      if (end_char == '}' && s->type == VAL_FUNC)
		return BOOT_SCRIPT_INVALID_SYM;

	      /* Check that assignment is valid.  */
	      if (c == '=' && s->type == VAL_FUNC)
		{
		  error = BOOT_SCRIPT_INVALID_ASG;
		  goto bad;
		}

	      /* For function symbols, execute the function.  */
	      if (s->type == VAL_FUNC)
		{
		  if (! s->run_on_exec)
		    {
		      (error
		       = ((*((int (*) (struct cmd *, int *)) s->val))
			  (cmd, &val)));
		      if (error)
			goto bad;
		      type = s->ret_type;
		    }
		  else
		    {
		      if (add_list (s, (void ***) &cmd->exec_funcs,
				    &cmd->exec_funcs_alloc,
				    &cmd->exec_funcs_index, 5))
			{
			  error = BOOT_SCRIPT_NOMEM;
			  goto bad;
			}
		      type = VAL_NONE;
		      goto out;
		    }
		}
	      else if (s->type == VAL_NONE)
		{
		  type = VAL_SYM;
		  val = (int) s;
 		}
	      else
		{
		  type = s->type;
		  val = s->val;
		}

	      if (sym)
		{
		  sym->type = type;
		  sym->val = val;
		}
	      else if (arg)
		{
		  arg->type = type;
		  arg->val = val;
		}

	    out:
	      p = q + 1;
	      if (c == end_char)
		{
		  /* Create an argument if necessary.
		     We create an argument if the symbol appears
		     in the expression by itself.

		     NOTE: This is temporary till the boot filesystem
		     servers support arguments.  When that happens,
		     symbol values will only be printed if they're
		     associated with an argument.  */
		  if (! arg && end_char == '}')
		    {
		      if (! add_arg (cmd, 0, type, val))
			{
			  error = BOOT_SCRIPT_NOMEM;
			  goto bad;
			}
		    }
		  arg = 0;
		  break;
		}
	      if (s->type != VAL_FUNC)
		sym = s;
	    }
	}
      else
	{
	  char c;

	  /* Command argument; just copy the text.  */
	  for (q = p;; q++)
	    {
	      if (! *q || *q == ' ' || *q == '\t' || *q == '\n')
		break;
	      if (*q == '$' && *(q + 1) == '{')
		break;
	    }
	  c = *q;
	  *q = '\0';

	  /* Add argument to list.  */
	  arg = add_arg (cmd, p, VAL_NONE, 0);
	  if (! arg)
	    {
	      error = BOOT_SCRIPT_NOMEM;
	      goto bad;
	    }
	  if (c == '$')
	    p = q;
	  else
	    {
	      if (c)
		p = q + 1;
	      else
		p = q;
	      arg = 0;
	    }
	}
    }


 bad:
  free_cmd (cmd, 1);
  cleanup (1);
  return error;
}