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 #ifndef LIBCURV_PROGRAM_H
6 #define LIBCURV_PROGRAM_H
7 
8 #include <libcurv/analyser.h>
9 #include <libcurv/frame.h>
10 #include <libcurv/meaning.h>
11 #include <libcurv/module.h>
12 #include <libcurv/scanner.h>
13 #include <libcurv/source.h>
14 #include <libcurv/system.h>
15 
16 namespace curv {
17 
18 // A Program is an object that is used to compile and run a Curv program.
19 // Since libcurv has no global variables, the 'global' state used to compile
20 // and run a program is created and managed by Program.
21 // After the program has been evaluated to a Value, the Program retains the
22 // program's source code and execution context, so that this context can be
23 // used to report a bad value error, via the At_Program context type.
24 //
25 // A Program progresses through 4 phases.
26 //  1. Construction. Constructs `sstate_`, the Source_State object,
27 //     containing global variables for compilation and runtime.
28 //  2. Compilation. Call one of the `compile()` methods to compile the
29 //     program's source code. Initializes `phrase_`, containing the parse
30 //     tree of the source code. Initializes internal members that
31 //     represent the executable form of the program.
32 //  3. Run the program by calling `eval()` or `exec()`.
33 //  4. After calling eval() to get a value, use At_Program(prog) as an
34 //     Exception context to report a bad value.
35 struct Program
36 {
37     Source_State sstate_;               // initialized by constructor
38     Shared<Phrase> phrase_ = nullptr;   // initialized by compile()
39 private:
40     // compiled program representation, initialized by compile()
41     Value value_{};
42     Shared<Meaning> meaning_ = nullptr;
43     Shared<Module_Expr> module_ = nullptr;
44     std::unique_ptr<Frame> frame_ = nullptr;
45 
46 public:
47     /*
48      * 1. construct the Program
49      */
50     Program(System& sys, Frame* file_frame = nullptr)
51     :
sstate_Program52         sstate_(sys, file_frame)
53     {}
54 
55     /*
56      * 2. compile the Program
57      */
58     // This is the general interface for compiling Curv source code.
59     // Several special-case shortcuts are also provided.
60     void compile(Shared<const Source>, Scanner_Opts, Environ&, Interp);
61 
62     // This shortcut leaves out Scanner_Opts,
63     // which only one specialized client uses.
64     void compile(Shared<const Source>, Environ&, Interp);
65 
66     // Compile an expression using the std_namespace. The common case.
67     void compile(Shared<const Source>);
68 
69     // Compile an expression using the std_namespace and a Scanner_Opts.
70     void compile(Shared<const Source>, Scanner_Opts);
71 
72     // The source is a file whose format is not Curv source code.
73     // It denotes a literal constant whose value was determined by the caller.
74     void compile(Filesystem::path, Source::Type, Value);
75 
76     /*
77      * 3. run the compiled Program
78      */
79     Shared<Module> exec(Operation::Executor&);
80     Value eval();
81 
82     /*
83      * 4. use the Program to report errors
84      */
85     const Phrase& syntax() const;
86 };
87 
88 } // namespace curv
89 #endif // header guard
90