dfsm: Trim error handling
[bendy-bus:bendy-bus.git] / dfsm / dfsm-ast-expression.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /*
3  * D-Bus Simulator
4  * Copyright (C) Philip Withnall 2011 <philip@tecnocode.co.uk>
5  * 
6  * D-Bus Simulator is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * D-Bus Simulator is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with D-Bus Simulator.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <glib.h>
21
22 #include "dfsm-ast-expression.h"
23 #include "dfsm-ast-object.h"
24
25 G_DEFINE_ABSTRACT_TYPE (DfsmAstExpression, dfsm_ast_expression, DFSM_TYPE_AST_NODE)
26
27 static void
28 dfsm_ast_expression_class_init (DfsmAstExpressionClass *klass)
29 {
30         /* Nothing to see here. */
31 }
32
33 static void
34 dfsm_ast_expression_init (DfsmAstExpression *self)
35 {
36         /* Nothing to see here. */
37 }
38
39 /**
40  * dfsm_ast_expression_calculate_type:
41  * @self: a #DfsmAstExpression
42  * @environment: a #DfsmEnvironment containing all defined variables
43  *
44  * Calculate the type of the given @expression. In some cases this may not be a definite type, for example if the expression is an empty data
45  * structure. In most cases, however, the type will be definite.
46  *
47  * This assumes that the expression has already been checked, and so this does not perform any type checking of its own.
48  *
49  * Return value: (transfer full): the type of the expression
50  */
51 GVariantType *
52 dfsm_ast_expression_calculate_type (DfsmAstExpression *self, DfsmEnvironment *environment)
53 {
54         DfsmAstExpressionClass *klass;
55
56         g_return_val_if_fail (DFSM_IS_AST_EXPRESSION (self), NULL);
57         g_return_val_if_fail (DFSM_IS_ENVIRONMENT (environment), NULL);
58
59         klass = DFSM_AST_EXPRESSION_GET_CLASS (self);
60
61         g_assert (klass->calculate_type != NULL);
62         return klass->calculate_type (self, environment);
63 }
64
65 /**
66  * dfsm_ast_expression_evaluate:
67  * @self: a #DfsmAstExpression
68  * @environment: a #DfsmEnvironment containing all defined variables
69  *
70  * Evaluate the given @expression in the given @environment. This will not modify the environment.
71  *
72  * This assumes that the expression has already been checked, and so this does not perform any type checking of its own.
73  *
74  * Return value: (transfer full): non-floating value of the expression
75  */
76 GVariant *
77 dfsm_ast_expression_evaluate (DfsmAstExpression *self, DfsmEnvironment *environment)
78 {
79         DfsmAstExpressionClass *klass;
80         GVariant *return_value;
81
82         g_return_val_if_fail (DFSM_IS_AST_EXPRESSION (self), NULL);
83         g_return_val_if_fail (DFSM_IS_ENVIRONMENT (environment), NULL);
84
85         klass = DFSM_AST_EXPRESSION_GET_CLASS (self);
86
87         g_assert (klass->evaluate != NULL);
88         return_value = klass->evaluate (self, environment);
89
90         g_assert (return_value != NULL && g_variant_is_floating (return_value) == FALSE);
91
92         return return_value;
93 }
94
95 /**
96  * dfsm_ast_expression_calculate_weight:
97  * @self: a #DfsmAstExpression
98  *
99  * Recursively calculates the weight of the expression and its children for the purposes of fuzzing. The higher the expression's weight, the more
100  * interesting it is to fuzz. For more information on weights, see dfsm_ast_data_structure_set_weight().
101  *
102  * Return value: weight of the expression
103  */
104 gdouble
105 dfsm_ast_expression_calculate_weight (DfsmAstExpression *self)
106 {
107         DfsmAstExpressionClass *klass;
108         gdouble return_value;
109
110         g_return_val_if_fail (DFSM_IS_AST_EXPRESSION (self), 0.0);
111
112         klass = DFSM_AST_EXPRESSION_GET_CLASS (self);
113
114         g_assert (klass->calculate_weight != NULL);
115         return_value = klass->calculate_weight (self);
116
117         /* Normalise the return value. */
118         if (return_value < 0.0) {
119                 return_value = 0.0;
120         }
121
122         return return_value;
123 }