Example #1
0
Type * TypeAllocVar(Var * var)
{
	Type * type;
	type = TypeAlloc(TYPE_VAR);
	type->typevar = var;
	return type;
}
Example #2
0
Type * TypeAllocArg(UInt8 arg_no, Type * arg_type)
{
	Type * type;

	type = TypeAlloc(TYPE_ARG);
	type->arg_no = arg_no;
	type->arg_type = arg_type;
	return type;
}
Example #3
0
Type * ParseTypeInline() 
/*
Syntax: "+" full_type | "(" full_type ")" | normal_type |  identifier | int ".." exp | "-" int ".." exp
*/{
	Type * type = NULL;
	Var * var;
	UInt16 bookmark;
	BigInt * bi;

	PARSE_INLINE = true;

	if (TOK == TOKEN_OPEN_P || TOK == TOKEN_PLUS) {
		type = ParseType2(INSTR_TYPE);
	} else {
		type = ParseType3();
		if (!TOK) return NULL;
		if (type != NULL) return type;

		if (ParseArg(&var)) {
			type = TypeAllocVar(var);
		} else if (TOK == TOKEN_ID) {
			bookmark = SetBookmark();
			var = ParseVariable();
			if (TOK) {
				if (var->mode == INSTR_TYPE) {
					type = var->type;
				} else if (var->mode == INSTR_VAR && var->type->variant == TYPE_TYPE) {
					type = var->type_value;
				} else {
					ErrArg(var);
					SyntaxErrorBmk("Variable [A] does not define type.", bookmark);
				}
			}
		} else if (TOK == TOKEN_INT || TOK == TOKEN_MINUS) {
			type = TypeAlloc(TYPE_INT);
			bi = ParseIntConstExpression(NULL);
			if (TOK) {
				IntModify(&type->range.min, bi);
				if (NextIs(TOKEN_DOTDOT)) {
					bi = ParseIntConstExpression(NULL);
					if (TOK) {
						IntModify(&type->range.max, bi);
					}
				} else {
					IntModify(&type->range.max, &type->range.min);
				}
			}
		}
	}
	return type;
}
Example #4
0
Type* GetCharArrayType (unsigned Len)
/* Return the type for a char array of the given length */
{
    /* Allocate memory for the type string */
    Type* T = TypeAlloc (3);    /* array/char/terminator */

    /* Fill the type string */
    T[0].C   = T_ARRAY;
    T[0].A.L = Len;             /* Array length is in the L attribute */
    T[1].C   = GetDefaultChar ();
    T[2].C   = T_END;

    /* Return the new type */
    return T;
}
Example #5
0
Type* PointerTo (const Type* T)
/* Return a type string that is "pointer to T". The type string is allocated
** on the heap and may be freed after use.
*/
{
    /* Get the size of the type string including the terminator */
    unsigned Size = TypeLen (T) + 1;

    /* Allocate the new type string */
    Type* P = TypeAlloc (Size + 1);

    /* Create the return type... */
    P[0].C = T_PTR | (T[0].C & T_QUAL_ADDRSIZE);
    memcpy (P+1, T, Size * sizeof (Type));

    /* ...and return it */
    return P;
}
Example #6
0
void TranslateInit()
{
    Var * var;
    UInt8 i;
    Type * type;

    // Create RULE procedure and allocate it's arguments

    type = TypeAlloc(TYPE_PROC);
    RULE_PROC = VarAlloc(INSTR_VAR, NULL, 0);
    RULE_PROC->type = type;

    for(i=0; i<MACRO_ARG_CNT; i++) {
        var = VarAllocScope(RULE_PROC, INSTR_VAR, NULL, i+1);
        var->submode = SUBMODE_ARG_IN;
        MACRO_ARG_VAR[i] = var;
    }

    RuleSetInit(&TRANSLATE_RULES);
    RuleSetInit(&INSTR_RULES);
}
Example #7
0
Type* GetImplicitFuncType (void)
/* Return a type string for an inplicitly declared function */
{
    /* Get a new function descriptor */
    FuncDesc* F = NewFuncDesc ();

    /* Allocate memory for the type string */
    Type* T = TypeAlloc (3);    /* func/returns int/terminator */

    /* Prepare the function descriptor */
    F->Flags  = FD_EMPTY | FD_VARIADIC;
    F->SymTab = &EmptySymTab;
    F->TagTab = &EmptySymTab;

    /* Fill the type string */
    T[0].C   = T_FUNC | CodeAddrSizeQualifier ();
    T[0].A.P = F;
    T[1].C   = T_INT;
    T[2].C   = T_END;

    /* Return the new type */
    return T;
}
int
main(int argc, char *argv[])
{
    int found, j, value;
    unsigned k, kk;
    char *s, *t;
    char *type_list = 0;
    char bfr[MAXPATHLEN];

    caseless = C_VALUE;

    while ((j = getopt(argc, argv, "cD:e:iI:prt:U:vVwW:x")) != EOF) {
	switch (j) {
	case 'V':
	    printf("conflict %s\n", RELEASE);
	    return (EXIT_SUCCESS);

	case 'c':
	    caseless = 0;
	    break;
	case 'i':
	    caseless = 1;
	    break;

	case 'e':
	    env_name = optarg;
	    break;
	case 't':
	    type_list = optarg;
	    break;
	case 'v':
	    v_opt++;
	    break;
	case 'p':
	    p_opt = TRUE;
	    break;

	case 'W':
	    value = (int) strtol(optarg, &t, 0);
	    if (*t != EOS || value < 0)
		usage();
	    value = (int) strlen(w_opt_text) - value;
	    if (value < 0)
		value = 0;
	    w_opt = w_opt_text + value;
	    break;

	case 'r':
	    acc_mask |= R_OK;
	    break;
	case 'w':
	    acc_mask |= W_OK;
	    break;
	case 'x':
	    acc_mask |= X_OK;
	    break;

	    /*
	     * The 'U' and 'D' options are parsed to simplify
	     * using C-preprocessor options to scan for include-
	     * files.
	     */
	case 'U':		/* ignored */
	    break;
	case 'D':		/* ignored */
	    break;
	case 'I':
	    AddToPath(optarg);
	    break;
	case 'L':
	    AddToPath(optarg);
	    break;

	default:
	    usage();
	    /*NOTREACHED */
	}
    }

    /* The "-v" and "-p" options aren't meaningful in combination */
    if (v_opt && p_opt)
	usage();

    /* The remaining arguments are the programs/symbols that we're looking
     * for.  Reduce the argument-list to the leaf-names (stripping paths).
     */
    if (argc > optind) {
	for (j = optind; j < argc; j++) {
	    argv[j] = MakeString(DOS_upper(fleaf(argv[j])));
	}
    }

    do_blips = ((v_opt > 1) && isatty(fileno(stderr)));

    if (acc_mask == 0)
	acc_mask = X_OK;

    /*
     * Get the current working-directory, so we have a reference point to
     * go back after scanning directories.
     */
    if (getwd(bfr) == 0)
	failed("getcwd");
    dot = MakeString(bfr);
    if (!p_opt)
	(void) printf("Current working directory is \"%s\"\n", dot);

    /*
     * Obtain the list of directories that we'll scan.
     */
    if (pathlist == 0) {
	if (env_name == 0)
	    env_name = "PATH";

	if ((s = getenv(env_name)) != 0)
	    pathlist = strdup(s);
	else
	    failed(env_name);

#if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX
	if (!strcmp(env_name, "PATH")) {
	    /* look in current directory before looking in $PATH */
	    s = malloc(strlen(pathlist) + 3);
	    (void) sprintf(s, ".%c%s", PATHLIST_SEP, pathlist);
	    free(pathlist);
	    pathlist = s;
	}
#endif
    }
    for (s = DOS_upper(pathlist), path_len = 1; *s != EOS; s++)
	if (*s == PATHLIST_SEP)
	    path_len++;
    dirs = TypeAlloc(DIRS, path_len);

    /*
     * Reconstruct the type-list (if any) as an array to simplify scanning.
     */
#ifdef TYPES_PATH
    if (type_list == 0) {
	if (!strcmp(env_name, "PATH"))
	    type_list = TYPES_PATH;
    }
#endif
    if (type_list != 0) {
	type_list = DOS_upper(strdup(type_list));
	for (s = type_list, num_types = 0; *s != EOS; s++) {
	    if (*s == '.') {
		num_types++;
#if NULL_FTYPE			/* "." and "" are different types */
		if ((s[1] == '.') || (s[1] == EOS))
		    num_types++;
#endif
	    }
	}
	if (num_types == 0 || *type_list != '.') {
	    (void) fprintf(stderr, "Type-list must be .-separated\n");
	    exit(EXIT_FAILURE);
	}
	FileTypes = TypeAlloc(char *, num_types);
	j = (int) num_types;
	do {
	    if (*--s == '.') {
		FileTypes[--j] = strdup(s);
#if NULL_FTYPE			/* "." and "" are different types */
		if (s[1] == EOS)
		    FileTypes[--j] = strdup("");
#endif
		*s = EOS;
	    }
	} while (j != 0);
	free(type_list);
    }
static void
ScanConflicts(char *path, unsigned inx, int argc, char **argv)
{
    DIR *dp;
    struct dirent *de;
    struct stat sb;
    int j;
    unsigned k;
#if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX
    char save_wd[MAXPATHLEN];
#endif

    /*
     * When scanning a directory, we first chdir to it, mostly to make
     * the scan+stat work faster, but also because some systems don't
     * scan properly otherwise.
     *
     * MSDOS and OS/2 are a little more complicated, because each drive
     * has its own current directory.
     */
#if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX
    (void) strcpy(save_wd, dot);
    if (!strcmp(".", path)) {
	path = dot;
    } else if (!same_drive(dot, path)) {
	if (!set_drive(path))
	    return;
	getwd(save_wd);
    }
#endif
    if (v_opt > 2)
	printf("ScanConflicts \"%s\"\n", path);

    if (set_directory(path)
	&& (dp = opendir(path)) != NULL) {

	while ((de = readdir(dp)) != NULL) {
	    register
	    type_t ok = 0;
	    int found = FALSE;
	    char buffer[MAXPATHLEN];
	    char *the_name;
	    char *the_NAME;

	    if (do_blips)
		blip('.');

	    (void) sprintf(buffer, "%.*s", (int) NAMLEN(de), de->d_name);
	    the_name = MakeString(DOS_upper(buffer));
	    the_NAME = ToCompare(the_name);

	    /* If arguments are given, restrict search to them */
	    if (argc > optind) {
		for (j = optind; j < argc; j++) {
		    if (SameName(argv[j], the_name)) {
			found = TRUE;
			break;
		    }
		}
		if (!found)
		    continue;
	    }

	    /* Verify that the name is a file, and executable */
	    if (stat(the_name, &sb) < 0)
		continue;
	    if ((sb.st_mode & S_IFMT) != S_IFREG)
		continue;

#if SYS_UNIX || SYS_OS2 || SYS_OS2_EMX
	    if (access(the_name, acc_mask) < 0)
		continue;
	    ok = 1;
#endif
	    if (FileTypes != 0) {
		if ((ok = LookupType(the_name)) == 0)
		    continue;
	    }

	    /* Find the name in our array of all names */
	    found = FALSE;
	    for (k = 0; k < total; k++) {
		if (SameName(inpath[k].ip_NAME, the_NAME)) {
		    FoundNode(&inpath[k], inx);
		    found = TRUE;
		    break;
		}
	    }

	    /* If not there, add it */
	    if (found) {
		if (the_NAME != the_name) {
		    FreeString(the_NAME);
		}
	    } else {
		if (!(total & CHUNK)) {
		    size_t need = (((total * 3) / 2) | CHUNK) + 1;
		    if (inpath != 0)
			inpath = TypeRealloc(INPATH, inpath, need);
		    else
			inpath = TypeAlloc(INPATH, need);
		}
		j = (int) total++;
		inpath[j].ip_name = the_name;
		inpath[j].ip_NAME = the_NAME;
		inpath[j].node = TypeAlloc(NODE, path_len);
		FoundNode(&inpath[j], inx);
	    }
	    if (v_opt > 2) {
		(void) printf("%c %s%c%s\n",
			      found ? '+' : '*',
			      path, PATHNAME_SEP, buffer);
	    }
	}
	(void) closedir(dp);
    }
#if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX
    if (strcmp(dot, save_wd)) {
	chdir(save_wd);
    }
#endif
    (void) set_directory(dot);
}
Example #10
0
/*
Type * ParseIntRange(Type * type)
{
	Var * min, * max;
	Bookmark bookmark;

	bookmark = SetBookmark();
	ParseExpressionType(TypeType(NULL));
	if (TOK && TOP != 0) {
		min = BufPop();
		max = NULL;
		if (NextIs(TOKEN_DOTDOT)) {
			ExpectExpression(NULL);
			if (TOK) {
				max = BufPop();
				type = TypeDerive(type);
			}
		}

		if (VarIsIntConst(min) && VarIsIntConst(max)) {
			type = TypeAllocRange(min, max);

			if (type->range.min > type->range.max) {
				SyntaxErrorBmk("range minimum bigger than maximum", bookmark);
			}

		} else {
			SyntaxErrorBmk("expected type constant expression", bookmark);
		}
	}
	return type;
}
*/
Type * ParseType2(InstrOp mode)
/*
Purpose:
	Parse: <int> [".." <int>] | <var> | proc <VarList>
Input:
	mode	Type of variable for which we parse.
*/
{
	
	Var * var;
	Type * type = NULL, * variant_type = NULL;
	Var * min, * max;
	Bookmark bookmark;

next:
	type = ParseType3();
	if (!TOK) return NULL;

	if (type == NULL) {
		bookmark = SetBookmark();
		ParseExpressionType(TypeType(NULL));
		if (TOK && TOP != 0) {
			min = BufPop();
			max = NULL;
			if (NextIs(TOKEN_DOTDOT)) {
				ExpectExpression(NULL);
				if (TOK) {
					max = BufPop();
				}
			}

			type = NULL;
			if (max == NULL) {
				var = min;
				if (var->mode == INSTR_TYPE) {
					type = var->type;
				} else if (var->mode == INSTR_VAR && var->type->variant == TYPE_TYPE) {
					type = var->type_value;
					SetFlagOn(var->submode, SUBMODE_USED_AS_TYPE);
				}

				// This is directly type
				if (type != NULL) {
					// For integer type, constants may be defined
					if (type->variant == TYPE_INT) {
//						type = ParseIntRange(type);
						goto const_list;
					}
					goto done;
				}
				max = var;		
			}

			if (VarIsIntConst(min) && VarIsIntConst(max)) {
				type = TypeAllocRange(min, max);

				if (type->range.min > type->range.max) {
					SyntaxErrorBmk("range minimum bigger than maximum", bookmark);
				}

			} else {
				SyntaxErrorBmk("expected type constant expression", bookmark);
			}
		} else if (TOK == TOKEN_STRING) {
			type = TypeAlloc(TYPE_VAR);
			type->typevar = VarNewStr(NAME);
			NextToken();
		}
	}

const_list:
	// Parse type specific constants
	// There can be list of constants specified in block.
	// First thing in the block must be an identifier, so we try to open the block with this in mind.
	// We try to parse constants only for integer types (in future, we may try other numberic or string types)

	if (type != NULL && type->variant == TYPE_INT && !type->is_enum) {
		if (TOK != TOKEN_OR) {
			type = ParseConstList(type);
		}
	}
done:
	if (TOK) {
		if (variant_type != NULL) {
			variant_type->right = type;
			type = variant_type;
		}

		if (NextIs(TOKEN_OR)) {
			variant_type = TypeAlloc(TYPE_VARIANT);
			variant_type->left = type;
			goto next;
		}
	}
	return type;
}
Example #11
0
Type * ParseType3()
{
	Type * type = NULL, * variant_type = NULL;
	Type * elmt, * t;
	Var * var;
	BigInt * st;

	//# "type" restrict_type
	if (NextIs(TOKEN_TYPE2)) {
		variant_type = ParseType2(INSTR_VAR);
		type = TypeType(variant_type);
	//# "enum" ["struct"]
	} else if (NextIs(TOKEN_ENUM)) {
		type = TypeAlloc(TYPE_INT);
		type->range.flexible = true;
		type->is_enum        = true;
		if (NextIs(TOKEN_STRUCT)) {
			ParseEnumStruct(type);
		} else {
			type = ParseConstList(type);
		}

	//# "proc" args
	} else if (NextIs(TOKEN_PROC)) {
		type = TypeAlloc(TYPE_PROC);
		ParseArgList(SUBMODE_ARG_IN, type);
		if (TOK) {
			ProcTypeFinalize(type);
		}
	//# "macro" args
	} else if (NextIs(TOKEN_MACRO)) {

		type = TypeAlloc(TYPE_MACRO);
		ParseArgList(SUBMODE_ARG_IN, type);

	// Struct
	} else if (NextIs(TOKEN_STRUCT)) {
		type = TypeAlloc(TYPE_STRUCT);
		ParseArgList(SUBMODE_EMPTY, type);

	// String
	} else if (NextIs(TOKEN_STRING_TYPE)) {
		type = TypeAlloc(TYPE_STRING);

	// Array
	} else if (NextIs(TOKEN_ARRAY)) {		
		type = TypeAlloc(TYPE_ARRAY);
		t = NULL;

		if (TOK == TOKEN_OPEN_P) {
			EnterBlockWithStop(TOKEN_EQUAL);
			while (TOK != TOKEN_ERROR && !NextIs(TOKEN_BLOCK_END)) {
				elmt = ParseIntType();
				if (type->index == NULL) {
					type->index = elmt;
				} else if (t != NULL) {
					t->right = TypeTuple(t->right, elmt);
					t = t->right;
				} else {
					t = TypeTuple(type->index, elmt);
					type->index = t;
				}
				NextIs(TOKEN_COMMA);
			};
		}
		
		// If no dimension has been defined, use flexible array.
		// This is possible only for constants now.

		if (TOK) {
			if (type->index == NULL) {
				elmt = TypeAlloc(TYPE_INT);
				elmt->range.flexible = true;
				elmt->range.min = 0;
				type->index = elmt;
			}
		}

		// Element STEP may be defined
		if (TOK) {
			if (NextIs(TOKEN_STEP)) {
				ExpectExpression(NULL);
				if (TOK) {
					var = STACK[0];
					st = VarIntConst(var);
					if (st != NULL) {
						type->step = IntN(st);
					} else {
						SyntaxError("Expected integer constant");
					}
				}
			}
		}

		if (TOK) {
			if (NextIs(TOKEN_OF)) {
				type->element = ParseSubtype();
			} else {
				type->element = TypeByte();
			}
		}

		if (TOK) {
			if (type->step == 0) {
				type->step = TypeSize(type->element);
			}
		}

	} else if (NextIs(TOKEN_ADR2)) {
		elmt = NULL;
		if (NextIs(TOKEN_OF)) {
			elmt = ParseSubtype();
		}
		type = TypeAdrOf(elmt);
	}
	return type;
}