213 lines
6.9 KiB
C
213 lines
6.9 KiB
C
/*
|
|
* DO NOT MODIFY THE CONTENTS OF THIS FILE.
|
|
* IT WILL BE REPLACED DURING GRADING
|
|
*/
|
|
|
|
/*
|
|
* The elements of this enumerated type are used in the "class" field
|
|
* of the "STMT" structure to specify the particular kind of statement
|
|
* that the structure represents. The parenthesized names in the comments
|
|
* indicate which element (if any) of the "members" union in the STMT
|
|
* structure is used by each kind of statement.
|
|
*/
|
|
typedef enum {
|
|
NO_STMT_CLASS,
|
|
LIST_STMT_CLASS, // "list" statement
|
|
DELETE_STMT_CLASS, // "delete" statement (delete_stmt)
|
|
RUN_STMT_CLASS, // "run" statement
|
|
CONT_STMT_CLASS, // "cont" statement
|
|
STOP_STMT_CLASS, // "stop" statement
|
|
WAIT_STMT_CLASS, // "wait" statement (jobctl_stmt)
|
|
POLL_STMT_CLASS, // "poll" statement (jobctl_stmt)
|
|
CANCEL_STMT_CLASS, // "cancel" statement (jobctl_stmt)
|
|
PAUSE_STMT_CLASS, // "pause" statement
|
|
SET_STMT_CLASS, // "set" statement (set_stmt)
|
|
UNSET_STMT_CLASS, // "unset" statement (unset_stmt)
|
|
IF_STMT_CLASS, // "if" statement (if_stmt)
|
|
GOTO_STMT_CLASS, // "goto" statement (goto_stmt)
|
|
SOURCE_STMT_CLASS, // "source" statement (source_stmt)
|
|
FG_STMT_CLASS, // pipeline run in foreground (sys_stmt)
|
|
BG_STMT_CLASS // pipeline run in background (sys_stmt)
|
|
} STMT_CLASS;
|
|
|
|
/*
|
|
* This structure is used to represent a statement.
|
|
* The value in the "class" field tells what kind of statement it is.
|
|
* Depending on this value, one of the fields of the "members" union
|
|
* may be valid.
|
|
*/
|
|
typedef struct stmt {
|
|
STMT_CLASS class;
|
|
int lineno;
|
|
union {
|
|
struct {
|
|
int from;
|
|
int to;
|
|
} delete_stmt;
|
|
struct {
|
|
struct pipeline *pipeline;
|
|
} sys_stmt;
|
|
struct {
|
|
struct expr *expr;
|
|
} jobctl_stmt;
|
|
struct {
|
|
char *name;
|
|
struct expr *expr;
|
|
} set_stmt;
|
|
struct {
|
|
char *name;
|
|
} unset_stmt;
|
|
struct {
|
|
struct expr *expr;
|
|
int lineno;
|
|
} if_stmt;
|
|
struct {
|
|
int lineno;
|
|
} goto_stmt;
|
|
struct {
|
|
char *file;
|
|
} source_stmt;
|
|
} members;
|
|
} STMT;
|
|
|
|
/*
|
|
* This structure is used to represent a command. The "args" field points
|
|
* to the head of as a nonempty linked list of "args" that make up the command.
|
|
* The first "arg" is interpreted as the name of the command; the remainder
|
|
* are arguments to it. The "next" field is used to link commands into a
|
|
* pipeline.
|
|
*/
|
|
typedef struct command {
|
|
struct arg *args;
|
|
struct command *next;
|
|
} COMMAND;
|
|
|
|
/*
|
|
* This structure is used to represent a "pipeline". The "commands" field
|
|
* points to the head of a nonempty list of commands. The "input_file" field,
|
|
* if non-NULL, is the name of a file from which input to the first command
|
|
* in the pipeline is to be redirected. Similarly, the "output_file" field,
|
|
* if non-NULL, is the name of a file to which output from the last command
|
|
* in the pipeline is to be redirected. If the "capture_output" field is
|
|
* nonzero, then instead of being redirected to a file, the output from the
|
|
* last command in the pipeline is to be redirected to a pipe. This pipe is
|
|
* to be read by the main process, which will "captures" the output and make
|
|
* it available as the value of a variable in the data store.
|
|
*/
|
|
typedef struct pipeline {
|
|
COMMAND *commands;
|
|
char *input_file;
|
|
char *output_file;
|
|
int capture_output;
|
|
} PIPELINE;
|
|
|
|
/*
|
|
* Values of this enumerated type are used to identify the various kinds
|
|
* of expressions.
|
|
*/
|
|
typedef enum {
|
|
NO_EXPR_CLASS,
|
|
LIT_EXPR_CLASS, // literal string (value)
|
|
NUM_EXPR_CLASS, // numeric variable (variable)
|
|
STRING_EXPR_CLASS, // string variable (variable)
|
|
UNARY_EXPR_CLASS, // unary expression (unary_expr)
|
|
BINARY_EXPR_CLASS // binary expression (binary_expr)
|
|
} EXPR_CLASS;
|
|
|
|
/*
|
|
* Values of this enumerated type are used to identify the various kinds
|
|
* of operators in expressions.
|
|
*/
|
|
typedef enum {
|
|
NO_OPRTR,
|
|
NOT_OPRTR, // "not" operator (unary_expr)
|
|
AND_OPRTR, // "and" operator (binary_expr)
|
|
OR_OPRTR, // "or" operator (binary_expr)
|
|
EQUAL_OPRTR, // "equal to" operator (binary_expr)
|
|
LESS_OPRTR, // "less than" operator (binary_expr)
|
|
GREATER_OPRTR, // "greater than" operator (binary_expr)
|
|
LESSEQ_OPRTR, // "less than or equal" operator (binary_expr)
|
|
GREATEQ_OPRTR, // "greater than or equal" operator (binary_expr)
|
|
PLUS_OPRTR, // "plus" (binary_expr)
|
|
MINUS_OPRTR, // "minus" (binary_expr)
|
|
TIMES_OPRTR, // "times" (binary_expr)
|
|
DIVIDE_OPRTR, // "divide" (binary_expr)
|
|
MOD_OPRTR // "mod" (binary_expr)
|
|
} OPRTR;
|
|
|
|
/*
|
|
* Values of this enumerated type are used to identify the various kinds
|
|
* values that an expression can have.
|
|
*/
|
|
typedef enum {
|
|
NO_VALUE_TYPE,
|
|
NUM_VALUE_TYPE, // numeric value
|
|
STRING_VALUE_TYPE // string value
|
|
} VALUE_TYPE;
|
|
|
|
/*
|
|
* This structure is used to represent an "expression".
|
|
*/
|
|
typedef struct expr {
|
|
EXPR_CLASS class;
|
|
VALUE_TYPE type;
|
|
union {
|
|
char *variable;
|
|
char *value;
|
|
struct {
|
|
OPRTR oprtr;
|
|
struct expr *arg;
|
|
} unary_expr;
|
|
struct {
|
|
OPRTR oprtr;
|
|
struct expr *arg1;
|
|
struct expr *arg2;
|
|
} binary_expr;
|
|
} members;
|
|
} EXPR;
|
|
|
|
/*
|
|
* This structure is used to represent an "argument", which is
|
|
* a single element of a command. Arguments contain arbitrary expressions,
|
|
* which allows commands to be constructed that depend on the values
|
|
* of variables.
|
|
*/
|
|
typedef struct arg {
|
|
EXPR *expr;
|
|
struct arg *next;
|
|
} ARG;
|
|
|
|
/*
|
|
* The following functions are used to print representations
|
|
* of the various syntactic objects to a specified output stream.
|
|
* A nonzero value for the "parens" argument of show_expr() causes
|
|
* a compound expression to be printed within enclosing parentheses.
|
|
*/
|
|
void show_stmt(FILE *file, STMT *stmt);
|
|
void show_pipeline(FILE *file, PIPELINE *pline);
|
|
void show_command(FILE *file, COMMAND *cmd);
|
|
void show_expr(FILE *file, EXPR *expr, int parens);
|
|
void show_oprtr(FILE *file, OPRTR oprtr);
|
|
void show_lineno(FILE *file, int lineno);
|
|
|
|
/*
|
|
* The following functions are use to free the various syntactic
|
|
* objects. Freeing an object with one of these functions implies
|
|
* freeing all the objects that it references.
|
|
*/
|
|
void free_stmt(STMT *stmt);
|
|
void free_pipeline(PIPELINE *pline);
|
|
void free_commands(COMMAND *cmd);
|
|
void free_args(ARG *args);
|
|
void free_expr(EXPR *expr);
|
|
void free_oprtr(OPRTR oprtr);
|
|
|
|
/*
|
|
* The following functions are use to make deep copies of the
|
|
* various syntactic objects.
|
|
*/
|
|
PIPELINE *copy_pipeline(PIPELINE *pline);
|
|
COMMAND *copy_commands(COMMAND *cmd);
|
|
ARG *copy_args(ARG *args);
|
|
EXPR *copy_expr(EXPR *expr);
|