📄 controller.c
字号:
result.payload.Array->size = size;
// Only call calloc if size > 0. Otherwise Electric Fence reports
// an error.
if (size > 0) {
// Allocate an new array of Tokens.
result.payload.Array->elements = (Token*) calloc(size, sizeof(Token));
if (given > 0) {
va_start(argp, given);
for (i = 0; i < given; i++) {
result.payload.Array->elements[i] = va_arg(argp, Token);
}
// elementType is given as the last argument.
elementType = va_arg(argp, int);
//result.payload.Array->elementType = elementType;
if (elementType >= 0) {
// convert the elements if needed.
for (i = 0; i < given; i++) {
if (Array_get(result, i).type != elementType) {
Array_set(result, i, functionTable[(int)elementType][FUNC_convert](Array_get(result, i)));
}
}
}
va_end(argp);
}
}
return result;
}
// Array_convert: Convert the first argument array
// into the type specified by the second argument.
// @param token The token to be converted.
// @param targetType The type to convert the elements of the given token to.
Token Array_convert(Token token, ...) {
int i;
Token result;
Token element;
va_list argp;
char targetType;
va_start(argp, token);
targetType = va_arg(argp, int);
result = Array_new(token.payload.Array->size, 0);
for (i = 0; i < token.payload.Array->size; i++) {
element = Array_get(token, i);
if (targetType != element.type) {
result.payload.Array->elements[i] = functionTable[(int)targetType][FUNC_convert](element);
} else {
result.payload.Array->elements[i] = element;
}
}
va_end(argp);
return result;
}
// Array_toString: Return a string token with a string representation
// of the specified array.
Token Array_toString(Token thisToken, ...) {
int i;
int currentSize, allocatedSize;
char* string;
Token elementString;
allocatedSize = 256;
string = (char*) malloc(allocatedSize);
string[0] = '{';
string[1] = '\0';
currentSize = 2;
for (i = 0; i < thisToken.payload.Array->size; i++) {
if (i != 0) {
strcat(string, ", ");
}
elementString = functionTable[(int)thisToken.payload.Array->elements[i].type][FUNC_toString](thisToken.payload.Array->elements[i]);
currentSize += strlen(elementString.payload.String);
if (currentSize > allocatedSize) {
allocatedSize *= 2;
string = (char*) realloc(string, allocatedSize);
}
strcat(string, elementString.payload.String);
free(elementString.payload.String);
}
strcat(string, "}");
return String_new(string);
}
// Array_isCloseTo: Test an array to see whether it is close in value to another.
Token Array_isCloseTo(Token thisToken, ...) {
int i;
va_list argp;
Token otherToken;
Token tolerance;
va_start(argp, thisToken);
otherToken = va_arg(argp, Token);
tolerance = va_arg(argp, Token);
if (thisToken.payload.Array->size != otherToken.payload.Array->size) {
return Boolean_new(false);
}
for (i = 0; i < thisToken.payload.Array->size; i++) {
if (!functionTable[(int)Array_get(thisToken, i).type][FUNC_isCloseTo](Array_get(thisToken, i), Array_get(otherToken, i), tolerance).payload.Boolean) {
return Boolean_new(false);
}
}
va_end(argp);
return Boolean_new(true);
}
// Array_multiply: Multiply an array by another array.
// Multiplication is element-wise.
// Assume the given otherToken is array type.
// Return a new Array token.
Token Array_multiply(Token thisToken, ...) {
int i;
int size1;
int size2;
int resultSize;
va_list argp;
Token result;
Token otherToken;
va_start(argp, thisToken);
otherToken = va_arg(argp, Token);
size1 = thisToken.payload.Array->size;
size2 = otherToken.payload.Array->size;
resultSize = (size1 > size2) ? size1 : size2;
result = Array_new(resultSize, 0);
for (i = 0; i < resultSize; i++) {
if (size1 == 1) {
result.payload.Array->elements[i] = functionTable[(int)Array_get(thisToken, 0).type][FUNC_multiply](Array_get(thisToken, 0), Array_get(otherToken, i));
} else if (size2 == 1) {
result.payload.Array->elements[i] = functionTable[(int)Array_get(otherToken, 0).type][FUNC_multiply](Array_get(thisToken, i), Array_get(otherToken, 0));
} else {
result.payload.Array->elements[i] = functionTable[(int)Array_get(thisToken, i).type][FUNC_multiply](Array_get(thisToken, i), Array_get(otherToken, i));
}
}
va_end(argp);
return result;
}
// Array_delete: FIXME: What does this do?
Token Array_delete(Token token, ...) {
int i;
Token element, emptyToken;
// Delete each elements.
for (i = 0; i < token.payload.Array->size; i++) {
element = Array_get(token, i);
functionTable[(int)element.type][FUNC_delete](element);
}
free(token.payload.Array->elements);
free(token.payload.Array);
/* We need to return something here because all the methods are declared
* as returning a Token so we can use them in a table of functions.
*/
return emptyToken;
}
// make a new integer token from the given value.
Token Double_new(double d) {
Token result;
result.type = TYPE_Double;
result.payload.Double = d;
return result;
}
Token Double_convert(Token token, ...) {
switch (token.type) {
#ifdef TYPE_String
case TYPE_String:
// FIXME: Is this safe?
token.type = TYPE_Double;
if (sscanf(token.payload.String, "%lg", &token.payload.Double) != 1) {
fprintf(stderr, "Double_convert(): failed to convert \"%s\" to a Double\n", token.payload.String);
exit(-1);
}
break;
#endif
#ifdef TYPE_Int
case TYPE_Int:
token.type = TYPE_Double;
token.payload.Double = InttoDouble(token.payload.Int);
break;
#endif
// FIXME: not finished
default:
fprintf(stderr, "Double_convert(): Conversion from an unsupported type. (%d)\n", token.type);
exit(-1);
break;
}
token.type = TYPE_Double;
return token;
}
Token Double_toString(Token thisToken, ...) {
return String_new(DoubletoString(thisToken.payload.Double));
}
Token Double_isCloseTo(Token thisToken, ...) {
va_list argp;
Token otherToken;
Token tolerance;
va_start(argp, thisToken);
otherToken = va_arg(argp, Token);
tolerance = va_arg(argp, Token);
va_end(argp);
return Boolean_new(fabs(thisToken.payload.Double - otherToken.payload.Double) < tolerance.payload.Double);
}
Token Double_multiply(Token thisToken, ...) {
va_list argp;
Token result;
Token otherToken;
va_start(argp, thisToken);
otherToken = va_arg(argp, Token);
switch (otherToken.type) {
case TYPE_Double:
result = Double_new(thisToken.payload.Double * otherToken.payload.Double);
break;
#ifdef TYPE_Int
case TYPE_Int:
result = Double_new(thisToken.payload.Double * otherToken.payload.Int);
break;
#endif
// FIXME: not finished
default:
fprintf(stderr, "Double_multiply(): Multiply with an unsupported type. (%d)\n", otherToken.type);
exit(1);
}
va_end(argp);
return result;
}
/* Instead of Double_delete(), we call scalarDelete(). */
// make a new integer token from the given value.
Token Boolean_new(boolean b) {
Token result;
result.type = TYPE_Boolean;
result.payload.Boolean = b;
return result;
}
Token Boolean_convert(Token token, ...) {
switch (token.type) {
// FIXME: not finished
default:
fprintf(stderr, "Boolean_convert(): Conversion from an unsupported type. (%d)", token.type);
break;
}
token.type = TYPE_Boolean;
return token;
}
Token Boolean_toString(Token thisToken, ...) {
return String_new(BooleantoString(thisToken.payload.Boolean));
}
Token Boolean_equals(Token thisToken, ...) {
va_list argp;
Token otherToken;
va_start(argp, thisToken);
otherToken = va_arg(argp, Token);
va_end(argp);
return Boolean_new(
( thisToken.payload.Boolean && otherToken.payload.Boolean ) ||
( !thisToken.payload.Boolean && !otherToken.payload.Boolean ));
}
/* Instead of Boolean_delete(), we call scalarDelete(). */
// make a new matrix from the given values
// assume that number of the rest of the arguments == length,
// and they are in the form of (element, element, ...).
// The rest of the arguments should be of type Token *.
Token Matrix_new(int row, int column, int given, ...) {
va_list argp;
int i;
Token result;
char elementType;
result.type = TYPE_Matrix;
result.payload.Matrix = (MatrixToken) malloc(sizeof(struct matrix));
result.payload.Matrix->row = row;
result.payload.Matrix->column = column;
// Allocate a new matrix of Tokens.
if (row > 0 && column > 0) {
// Allocate an new 2-D array of Tokens.
result.payload.Matrix->elements = (Token*) calloc(row * column, sizeof(Token));
if (given > 0) {
// Set the first element.
va_start(argp, given);
for (i = 0; i < given; i++) {
result.payload.Matrix->elements[i] = va_arg(argp, Token);
}
// elementType is given as the last argument.
elementType = va_arg(argp, int);
if (elementType >= 0) {
// convert the elements if needed.
for (i = 0; i < given; i++) {
if (Matrix_get(result, i, 0).type != elementType) {
result.payload.Matrix->elements[i] = functionTable[(int)elementType][FUNC_convert](Matrix_get(result, i, 0));
}
}
}
va_end(argp);
}
}
return result;
}
Token Matrix_convert(Token token, ...) {
/* token.payload.Matrix = (MatrixToken) malloc(sizeof(struct matrix));
token.payload.Matrix->row = 1;
token.payload.Matrix->column = 1;
result.payload.Matrix->elements = (Token*) calloc(1, sizeof(Token));
token.type = TYPE_Matrix;
Matrix_set(token, 0, 0, token);
return token;
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -