#include <stdio.h>
#include <math.h>
typedef enum { CONSTANT, VARIABLE, OPERATOR } ExpressionType;
typedef struct {
ExpressionType expressionType;
void* expression;
} Expression;
typedef struct {} Variable;
typedef struct {
float value;
} Constant;
typedef enum { PLUS, MINUS, MULTIPLY, DIVIDE } OperatorType;
typedef struct {
OperatorType operatorType;
Expression a;
Expression b;
} Operator;
typedef struct {
Variable* variable;
float value;
} Binding;
typedef struct {
Binding* bindings;
size_t size;
} Context;
float value(Variable* variable, Context context) {
for (size_t i = 0; i < context.size; i++) {
if (context.bindings[i].variable == variable) {
return context.bindings[i].value;
}
}
return NAN;
}
float result(Expression expression, Context context);
float resultOfOperator(Operator* op, Context context) {
float aResult = result(op->a, context);
float bResult = result(op->b, context);
switch (op->operatorType) {
case PLUS:
return aResult + bResult;
case MINUS:
return aResult - bResult;
case MULTIPLY:
return aResult * bResult;
case DIVIDE:
return aResult / bResult;
}
return NAN;
}
float result(Expression expression, Context context) {
switch (expression.expressionType) {
case CONSTANT:
return *(float*)expression.expression;
case VARIABLE:
return value((Variable*)expression.expression, context);
case OPERATOR:
return resultOfOperator((Operator*)expression.expression, context);
}
return NAN;
}
int main(void) {
Variable a;
Variable b;
Variable c;
Variable d;
Constant five = { 5.0 };
Operator divide = { DIVIDE, { VARIABLE, &a }, { VARIABLE, &b } };
Operator multiply = { MULTIPLY, { OPERATOR, ÷ }, { VARIABLE, &c } };
Operator minus = { MINUS, { OPERATOR, &multiply }, { VARIABLE, &d } };
Operator plus = { PLUS, { OPERATOR, &minus }, { CONSTANT, &five } };
Expression expression = { OPERATOR, &plus };
Binding bindings[] = { { &a, 1.0 }, { &b, 2.0 }, { &c, 3.0 }, { &d, 4.0 } };
Context context = { bindings, sizeof bindings };
printf("%f", result
(expression
, context
));
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxtYXRoLmg+Cgp0eXBlZGVmIGVudW0geyBDT05TVEFOVCwgVkFSSUFCTEUsIE9QRVJBVE9SIH0gRXhwcmVzc2lvblR5cGU7Cgp0eXBlZGVmIHN0cnVjdCB7CglFeHByZXNzaW9uVHlwZSBleHByZXNzaW9uVHlwZTsKCXZvaWQqIGV4cHJlc3Npb247Cn0gRXhwcmVzc2lvbjsKCnR5cGVkZWYgc3RydWN0IHt9IFZhcmlhYmxlOwoKdHlwZWRlZiBzdHJ1Y3QgewoJZmxvYXQgdmFsdWU7Cn0gQ29uc3RhbnQ7Cgp0eXBlZGVmIGVudW0geyBQTFVTLCBNSU5VUywgTVVMVElQTFksIERJVklERSB9IE9wZXJhdG9yVHlwZTsKCnR5cGVkZWYgc3RydWN0IHsKCU9wZXJhdG9yVHlwZSBvcGVyYXRvclR5cGU7CglFeHByZXNzaW9uIGE7CglFeHByZXNzaW9uIGI7Cn0gT3BlcmF0b3I7Cgp0eXBlZGVmIHN0cnVjdCB7CglWYXJpYWJsZSogdmFyaWFibGU7CglmbG9hdCB2YWx1ZTsKfSBCaW5kaW5nOwoKdHlwZWRlZiBzdHJ1Y3QgewoJQmluZGluZyogYmluZGluZ3M7CglzaXplX3Qgc2l6ZTsKfSBDb250ZXh0OwoKZmxvYXQgdmFsdWUoVmFyaWFibGUqIHZhcmlhYmxlLCBDb250ZXh0IGNvbnRleHQpIHsKCWZvciAoc2l6ZV90IGkgPSAwOyBpIDwgY29udGV4dC5zaXplOyBpKyspIHsKCQlpZiAoY29udGV4dC5iaW5kaW5nc1tpXS52YXJpYWJsZSA9PSB2YXJpYWJsZSkgewoJCQlyZXR1cm4gY29udGV4dC5iaW5kaW5nc1tpXS52YWx1ZTsKCQl9Cgl9CgoJcmV0dXJuIE5BTjsKfQoKZmxvYXQgcmVzdWx0KEV4cHJlc3Npb24gZXhwcmVzc2lvbiwgQ29udGV4dCBjb250ZXh0KTsKCmZsb2F0IHJlc3VsdE9mT3BlcmF0b3IoT3BlcmF0b3IqIG9wLCBDb250ZXh0IGNvbnRleHQpIHsKCWZsb2F0IGFSZXN1bHQgPSByZXN1bHQob3AtPmEsIGNvbnRleHQpOwoJZmxvYXQgYlJlc3VsdCA9IHJlc3VsdChvcC0+YiwgY29udGV4dCk7CgkKCXN3aXRjaCAob3AtPm9wZXJhdG9yVHlwZSkgewoJY2FzZSBQTFVTOgoJCXJldHVybiBhUmVzdWx0ICsgYlJlc3VsdDsKCgljYXNlIE1JTlVTOgoJCXJldHVybiBhUmVzdWx0IC0gYlJlc3VsdDsKCgljYXNlIE1VTFRJUExZOgoJCXJldHVybiBhUmVzdWx0ICogYlJlc3VsdDsKCgljYXNlIERJVklERToKCQlyZXR1cm4gYVJlc3VsdCAvIGJSZXN1bHQ7Cgl9CgkKCXJldHVybiBOQU47Cn0KCmZsb2F0IHJlc3VsdChFeHByZXNzaW9uIGV4cHJlc3Npb24sIENvbnRleHQgY29udGV4dCkgewoJc3dpdGNoIChleHByZXNzaW9uLmV4cHJlc3Npb25UeXBlKSB7CgljYXNlIENPTlNUQU5UOgoJCXJldHVybiAqKGZsb2F0KilleHByZXNzaW9uLmV4cHJlc3Npb247CgkKCWNhc2UgVkFSSUFCTEU6CgkJcmV0dXJuIHZhbHVlKChWYXJpYWJsZSopZXhwcmVzc2lvbi5leHByZXNzaW9uLCBjb250ZXh0KTsKCgljYXNlIE9QRVJBVE9SOgoJCXJldHVybiByZXN1bHRPZk9wZXJhdG9yKChPcGVyYXRvciopZXhwcmVzc2lvbi5leHByZXNzaW9uLCBjb250ZXh0KTsKCX0KCQoJcmV0dXJuIE5BTjsKfQoKaW50IG1haW4odm9pZCkgewoJVmFyaWFibGUgYTsKCVZhcmlhYmxlIGI7CglWYXJpYWJsZSBjOwoJVmFyaWFibGUgZDsKCglDb25zdGFudCBmaXZlID0geyA1LjAgfTsKCU9wZXJhdG9yIGRpdmlkZSA9IHsgRElWSURFLCB7IFZBUklBQkxFLCAmYSB9LCB7IFZBUklBQkxFLCAmYiB9IH07CglPcGVyYXRvciBtdWx0aXBseSA9IHsgTVVMVElQTFksIHsgT1BFUkFUT1IsICZkaXZpZGUgfSwgeyBWQVJJQUJMRSwgJmMgfSB9OwoJT3BlcmF0b3IgbWludXMgPSB7IE1JTlVTLCB7IE9QRVJBVE9SLCAmbXVsdGlwbHkgfSwgeyBWQVJJQUJMRSwgJmQgfSB9OwoJT3BlcmF0b3IgcGx1cyA9IHsgUExVUywgeyBPUEVSQVRPUiwgJm1pbnVzIH0sIHsgQ09OU1RBTlQsICZmaXZlIH0gfTsKCglFeHByZXNzaW9uIGV4cHJlc3Npb24gPSB7IE9QRVJBVE9SLCAmcGx1cyB9OwoKCUJpbmRpbmcgYmluZGluZ3NbXSA9IHsgeyAmYSwgMS4wIH0sIHsgJmIsIDIuMCB9LCB7ICZjLCAzLjAgfSwgeyAmZCwgNC4wIH0gfTsKCUNvbnRleHQgY29udGV4dCA9IHsgYmluZGluZ3MsIHNpemVvZiBiaW5kaW5ncyB9OwoJcHJpbnRmKCIlZiIsIHJlc3VsdChleHByZXNzaW9uLCBjb250ZXh0KSk7CgoJcmV0dXJuIDA7Cn0K