1 // Copyright 2016-2021 Doug Moen
2 // Licensed under the Apache License, version 2.0
3 // See accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0
4 
5 #include <libcurv/analyser.h>
6 #include <libcurv/function.h>
7 #include <libcurv/sc_compiler.h>
8 #include <libcurv/sc_context.h>
9 
10 namespace curv {
11 
12 void
get_locations(std::list<Func_Loc> & locs) const13 At_SC_Frame::get_locations(std::list<Func_Loc>& locs) const
14 {
15     get_sc_frame_locations(&call_frame_, locs);
16 }
system() const17 System& At_SC_Frame::system() const { return call_frame_.sc_.sstate_.system_; }
frame() const18 Frame* At_SC_Frame::frame() const { return nullptr; }
19 
20 Shared<const String>
rewrite_message(Shared<const String> msg) const21 At_SC_Frame::rewrite_message(Shared<const String> msg) const
22 {
23     return sc_frame_rewrite_message(&call_frame_, msg);
24 }
25 
sc_frame_caller(const SC_Frame & f)26 Shared<const Function> sc_frame_caller(const SC_Frame& f)
27 {
28     if (auto pf = f.parent_frame_)
29         return pf->func_;
30     return nullptr;
31 }
32 void
get_sc_frame_locations(const SC_Frame * f,std::list<Func_Loc> & locs)33 get_sc_frame_locations(const SC_Frame* f, std::list<Func_Loc>& locs)
34 {
35     for (; f != nullptr; f = f->parent_frame_) {
36         if (f->call_phrase_ != nullptr)
37             locs.emplace_back(sc_frame_caller(*f), f->call_phrase_->location());
38         if (f->root_context_ != nullptr)
39             f->root_context_->get_locations(locs);
40     }
41 }
42 
43 Shared<const String>
sc_frame_rewrite_message(const SC_Frame * f,Shared<const String> msg)44 sc_frame_rewrite_message(const SC_Frame* f, Shared<const String> msg)
45 {
46     for (; f != nullptr; f = f->parent_frame_) {
47         if (f->root_context_ != nullptr)
48             msg = f->root_context_->rewrite_message(msg);
49     }
50     msg = stringify("Shape Compiler: ", msg);
51     return msg;
52 }
53 
At_SC_Phrase(Shared<const Phrase> phrase,SC_Frame & frame)54 At_SC_Phrase::At_SC_Phrase(Shared<const Phrase> phrase, SC_Frame& frame)
55 : phrase_(move(phrase)), call_frame_(frame)
56 {}
57 
58 void
get_locations(std::list<Func_Loc> & locs) const59 At_SC_Phrase::get_locations(std::list<Func_Loc>& locs) const
60 {
61     if (phrase_)
62         locs.emplace_back(call_frame_.func_, phrase_->location());
63     get_sc_frame_locations(&call_frame_, locs);
64 }
system() const65 System& At_SC_Phrase::system() const { return call_frame_.sc_.sstate_.system_; }
frame() const66 Frame* At_SC_Phrase::frame() const { return nullptr; }
syntax() const67 const Phrase& At_SC_Phrase::syntax() const { return *phrase_; }
68 
69 Shared<const String>
rewrite_message(Shared<const String> msg) const70 At_SC_Phrase::rewrite_message(Shared<const String> msg) const
71 {
72     return sc_frame_rewrite_message(&call_frame_, msg);
73 }
74 
get_locations(std::list<Func_Loc> & locs) const75 void At_SC_Tuple_Arg::get_locations(std::list<Func_Loc>& locs) const
76 {
77     get_sc_frame_locations(&call_frame_, locs);
78 }
system() const79 System& At_SC_Tuple_Arg::system() const { return call_frame_.sc_.sstate_.system_; }
frame() const80 Frame* At_SC_Tuple_Arg::frame() const { return nullptr; }
81 
82 Shared<const String>
rewrite_message(Shared<const String> msg) const83 At_SC_Tuple_Arg::rewrite_message(Shared<const String> msg) const
84 {
85     return sc_frame_rewrite_message(&call_frame_,
86         stringify("argument[",tuple_index_,"]: ", msg));
87 }
88 
89 void
get_locations(std::list<Func_Loc> & locs) const90 At_SC_Arg_Expr::get_locations(std::list<Func_Loc>& locs) const
91 {
92     locs.emplace_back(sc_frame_caller(parent_frame_),
93         arg_part(call_phrase_)->location());
94     get_sc_frame_locations(&parent_frame_, locs);
95 }
96 Shared<const String>
rewrite_message(Shared<const String> msg) const97 At_SC_Arg_Expr::rewrite_message(Shared<const String> msg) const
98 {
99     if (func_.name_.empty())
100         msg = stringify("function argument: ",msg);
101     else
102        msg = stringify("argument #",func_.argpos_+1," of ",func_.name_,": ",msg);
103     return sc_frame_rewrite_message(&parent_frame_, msg);
104 }
105 System&
system() const106 At_SC_Arg_Expr::system() const
107 {
108     return parent_frame_.sc_.sstate_.system_;
109 }
110 Frame*
frame() const111 At_SC_Arg_Expr::frame() const
112 {
113     return nullptr;
114 }
115 const Phrase&
syntax() const116 At_SC_Arg_Expr::syntax() const
117 {
118     return *arg_part(call_phrase_);
119 }
120 
121 } // namespace curv
122