forked from GaijinEntertainment/daScript
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathast_annotations.cpp
96 lines (91 loc) · 3.92 KB
/
ast_annotations.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
#include "daScript/misc/platform.h"
#include "daScript/ast/ast.h"
#include "daScript/ast/ast_visitor.h"
#include "daScript/misc/lookup1.h"
namespace das
{
class FinAnnotationVisitor : public Visitor {
public:
FinAnnotationVisitor( const ProgramPtr & prog ) {
program = prog;
}
protected:
ProgramPtr program;
protected:
virtual void preVisit ( Structure * var ) override {
Visitor::preVisit(var);
for ( const auto & pA : var->annotations ) {
if (pA->annotation->rtti_isStructureAnnotation()) {
auto sa = static_pointer_cast<StructureAnnotation>(pA->annotation);
string err = "";
if (!sa->look(var->shared_from_this(), *program->thisModuleGroup, pA->arguments, err)) {
program->error("can't 'look' with structure annotation\n" + err, var->at, CompilationError::invalid_annotation);
}
}
}
}
virtual void preVisit ( Function * fn ) override {
Visitor::preVisit(fn);
for ( const auto & an : fn->annotations ) {
auto fna = static_pointer_cast<FunctionAnnotation>(an->annotation);
string err = "";
if ( !fna->finalize(fn->shared_from_this(), *program->thisModuleGroup, an->arguments, program->options, err) ) {
program->error("can't finalize annotation\n" + err, fn->at, CompilationError::invalid_annotation);
}
}
}
virtual void preVisit ( ExprBlock * block ) override {
Visitor::preVisit(block);
if ( block->annotations.size() ) {
for ( const auto & an : block->annotations ) {
auto fna = static_pointer_cast<FunctionAnnotation>(an->annotation);
string err = "";
if ( !fna->finalize(block, *program->thisModuleGroup, an->arguments, program->options, err) ) {
program->error("can't finalize annotation\n" + err, block->at, CompilationError::invalid_annotation);
}
}
if ( block->annotationDataSid || block->annotationData ) {
if ( block->annotationDataSid && block->annotationData ) {
program->thisModule->annotationData[block->annotationDataSid] = block->annotationData;
} else {
program->error("internal error. both annotationData and Sid must be provided",
block->at, CompilationError::invalid_annotation);
}
}
}
}
void skipMakeBlock ( const ExpressionPtr & expr ) {
if ( expr->rtti_isMakeBlock() ) {
auto mkb = static_pointer_cast<ExprMakeBlock>(expr);
auto blk = static_pointer_cast<ExprBlock>(mkb->block);
blk->aotSkipMakeBlock = true;
}
}
virtual void preVisit ( ExprCall * call ) override {
Visitor::preVisit(call);
if ( call->func->aotTemplate ) {
for ( auto & arg : call->arguments ) {
skipMakeBlock(arg);
}
}
}
virtual void preVisit ( ExprOp1 * op1 ) override {
Visitor::preVisit(op1);
skipMakeBlock(op1->subexpr);
}
virtual void preVisit ( ExprOp2 * op2 ) override {
Visitor::preVisit(op2);
skipMakeBlock(op2->left);
skipMakeBlock(op2->right);
}
virtual void preVisit ( ExprOp3 * op3 ) override {
Visitor::preVisit(op3);
skipMakeBlock(op3->left);
skipMakeBlock(op3->right);
}
};
void Program::finalizeAnnotations() {
FinAnnotationVisitor fin(shared_from_this());
visit(fin);
}
}