-
Notifications
You must be signed in to change notification settings - Fork 0
/
Procedure.cpp
109 lines (90 loc) · 2.94 KB
/
Procedure.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "Procedure.hpp"
ProcedureHeading::ProcedureHeading(Identifier identifier):
ProcedureHeading(identifier, new FormalParameters())
{
}
ProcedureHeading::ProcedureHeading(Identifier identifier, FormalParameters* formalParameters):
identifier(identifier), formalParameters(formalParameters)
{
}
ProcedureHeading::~ProcedureHeading() {}
ProcedureBody::ProcedureBody():
ProcedureBody(new Declarations())
{
}
ProcedureBody::ProcedureBody(Declarations* declarations):
ProcedureBody(declarations, new StatementSequence())
{
}
ProcedureBody::ProcedureBody(Declarations* declarations, StatementSequence* procedureBlock):
declarations(declarations), procedureBlock(procedureBlock)
{
}
ProcedureBody::~ProcedureBody() {}
void ProcedureDeclaration::declare(Context& context)
{
Identifier identifier = procedureHeading->identifier;
//std::cerr << "Declaring procedure " << identifier << std::endl;
context.declareProcedure(identifier, new Procedure(procedureHeading, procedureBody));
}
void ProcedureDeclarations::declare(Context& context)
{
//std::cerr << "Declaring procedures" << std::endl;
for (auto& declaration : procedureDelcarations)
{
declaration->declare(context);
}
}
void ProcedureDeclarations::addDeclaration(ProcedureDeclaration* procedureDeclaration)
{
procedureDelcarations.push_back(procedureDeclaration);
}
void Procedure::call(ActualParameters* actualParameters, Context& context)
{
//std::cerr << "calling procedure " << procedureHeading->identifier << std::endl;
/* TODO: add function to context to go deeper */
context.currentLevel++;
std::vector<Expression*>& actualParametersExpressions =
actualParameters->expressionSequence->expressions;
int parameterIndex = 0;
std::vector<FormalParametersSection*>& formalParametersSections =
procedureHeading->formalParameters->formalParametersSectionSequence->formalParametersSections;
for(auto& section : formalParametersSections)
{
for(auto& identifier : section->identifierList->identifiers)
{
if (parameterIndex >= actualParametersExpressions.size())
{
throw wrong_arguments_number("Wrong agruments number in procedure "
+ procedureHeading->identifier);
}
if (section->isVar)
{
Value* variable =
actualParametersExpressions[parameterIndex]->evaluate(context);
context.declareAndReferenceVariable(identifier, variable);
++parameterIndex;
}
else
{
context.declareAndSetVariable(identifier,
actualParametersExpressions[parameterIndex]->evaluate(context));
++parameterIndex;
}
}
}
procedureBody->declarations->declare(context);
procedureBody->procedureBlock->execute(context);
context.removeObsoleteVariables();
context.restoreShadowedVariables();
context.currentLevel--;
}
ActualParameters::ActualParameters():
ActualParameters(new ExpressionSequence())
{
}
ActualParameters::ActualParameters(ExpressionSequence* expressionSequence):
expressionSequence(expressionSequence)
{
}
ActualParameters::~ActualParameters() {}