+ case TOK_IDENT:
+ /* Identifier. Get a pointer to the symbol table entry */
+ Sym = E->Sym = FindSym (CurTok.Ident);
+
+ /* Is the symbol known? */
+ if (Sym) {
+
+ /* We found the symbol - skip the name token */
+ NextToken ();
+
+ /* Check for illegal symbol types */
+ CHECK ((Sym->Flags & SC_LABEL) != SC_LABEL);
+ if (Sym->Flags & SC_TYPE) {
+ /* Cannot use type symbols */
+ Error ("Variable identifier expected");
+ /* Assume an int type to make E valid */
+ E->Flags = E_LOC_STACK | E_RTYPE_LVAL;
+ E->Type = type_int;
+ return;
+ }
+
+ /* Mark the symbol as referenced */
+ Sym->Flags |= SC_REF;
+
+ /* The expression type is the symbol type */
+ E->Type = Sym->Type;
+
+ /* Check for legal symbol types */
+ if ((Sym->Flags & SC_CONST) == SC_CONST) {
+ /* Enum or some other numeric constant */
+ E->Flags = E_LOC_ABS | E_RTYPE_RVAL;
+ E->Val = Sym->V.ConstVal;
+ } else if ((Sym->Flags & SC_FUNC) == SC_FUNC) {
+ /* Function */
+ E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
+ E->Name = (unsigned long) Sym->Name;
+ } else if ((Sym->Flags & SC_AUTO) == SC_AUTO) {
+ /* Local variable. If this is a parameter for a variadic
+ * function, we have to add some address calculations, and the
+ * address is not const.
+ */
+ if ((Sym->Flags & SC_PARAM) == SC_PARAM && F_IsVariadic (CurrentFunc)) {
+ /* Variadic parameter */
+ g_leavariadic (Sym->V.Offs - F_GetParamSize (CurrentFunc));
+ E->Flags = E_LOC_EXPR | E_RTYPE_LVAL;
+ } else {
+ /* Normal parameter */
+ E->Flags = E_LOC_STACK | E_RTYPE_LVAL;
+ E->Val = Sym->V.Offs;
+ }
+ } else if ((Sym->Flags & SC_REGISTER) == SC_REGISTER) {
+ /* Register variable, zero page based */
+ E->Flags = E_LOC_REGISTER | E_RTYPE_LVAL;
+ E->Name = Sym->V.R.RegOffs;
+ } else if ((Sym->Flags & SC_STATIC) == SC_STATIC) {
+ /* Static variable */
+ if (Sym->Flags & (SC_EXTERN | SC_STORAGE)) {
+ E->Flags = E_LOC_GLOBAL | E_RTYPE_LVAL;
+ E->Name = (unsigned long) Sym->Name;
+ } else {
+ E->Flags = E_LOC_STATIC | E_RTYPE_LVAL;
+ E->Name = Sym->V.Label;
+ }
+ } else {
+ /* Local static variable */
+ E->Flags = E_LOC_STATIC | E_RTYPE_LVAL;
+ E->Name = Sym->V.Offs;
+ }
+
+ /* We've made all variables lvalues above. However, this is
+ * not always correct: An array is actually the address of its
+ * first element, which is a rvalue, and a function is a
+ * rvalue, too, because we cannot store anything in a function.
+ * So fix the flags depending on the type.
+ */
+ if (IsTypeArray (E->Type) || IsTypeFunc (E->Type)) {
+ ED_MakeRVal (E);
+ }
+
+ } else {
+
+ /* We did not find the symbol. Remember the name, then skip it */
+ ident Ident;
+ strcpy (Ident, CurTok.Ident);
+ NextToken ();
+
+ /* IDENT is either an auto-declared function or an undefined variable. */
+ if (CurTok.Tok == TOK_LPAREN) {
+ /* Declare a function returning int. For that purpose, prepare a
+ * function signature for a function having an empty param list
+ * and returning int.
+ */
+ Warning ("Function call without a prototype");
+ Sym = AddGlobalSym (Ident, GetImplicitFuncType(), SC_EXTERN | SC_REF | SC_FUNC);
+ E->Type = Sym->Type;
+ E->Flags = E_LOC_GLOBAL | E_RTYPE_RVAL;
+ E->Name = (unsigned long) Sym->Name;
+ } else {
+ /* Undeclared Variable */
+ Sym = AddLocalSym (Ident, type_int, SC_AUTO | SC_REF, 0);
+ E->Flags = E_LOC_STACK | E_RTYPE_LVAL;
+ E->Type = type_int;
+ Error ("Undefined symbol: `%s'", Ident);
+ }
+
+ }
+ break;
+
+ case TOK_SCONST:
+ /* String literal */
+ E->Type = GetCharArrayType (GetLiteralPoolOffs () - CurTok.IVal);
+ E->Flags = E_LOC_LITERAL | E_RTYPE_RVAL;
+ E->Val = CurTok.IVal;
+ E->Name = LiteralPoolLabel;
+ NextToken ();
+ break;
+
+ case TOK_ASM:
+ /* ASM statement */
+ AsmStatement ();
+ E->Flags = E_LOC_EXPR | E_RTYPE_RVAL;
+ E->Type = type_void;
+ break;
+
+ case TOK_A:
+ /* Register pseudo variable */
+ E->Type = type_uchar;
+ E->Flags = E_LOC_PRIMARY | E_RTYPE_LVAL;
+ NextToken ();
+ break;
+
+ case TOK_AX:
+ /* Register pseudo variable */
+ E->Type = type_uint;
+ E->Flags = E_LOC_PRIMARY | E_RTYPE_LVAL;
+ NextToken ();
+ break;
+
+ case TOK_EAX:
+ /* Register pseudo variable */
+ E->Type = type_ulong;
+ E->Flags = E_LOC_PRIMARY | E_RTYPE_LVAL;
+ NextToken ();
+ break;
+
+ default:
+ /* Illegal primary. */
+ Error ("Expression expected");
+ ED_MakeConstAbsInt (E, 1);
+ break;