Undo 3272. The trouble with creating a new section for constants is that
there's no good place to order it since constants can be initialized
using globals as well as vice versa. And I don't want to add constraints
disallowing either side.

Instead, a new plan: always declare constants in the Globals section
using 'extern const' rather than just 'const', since otherwise constants
implicitly have internal linkage (http://stackoverflow.com/questions/14894698/why-does-extern-const-int-n-not-work-as-expected)
This commit is contained in:
Kartik K. Agaram 2016-08-28 18:12:03 -07:00
parent c7fde8d4e4
commit 5f05e954ee
11 changed files with 34 additions and 28 deletions

View File

@ -94,20 +94,22 @@
// Types
// End Types
// prototypes are auto-generated in the makefile; define your functions in any order
// Prototypes are auto-generated in the makefile; define your functions in any
// order. Just be sure to declare each function header all on one line. Our
// auto-generation scripts are too minimal and simple-minded to handle
// anything else.
#include "function_list" // by convention, files ending with '_list' are auto-generated
// Globals
//
// (Code in this section should strictly consist only of single-line variable
// definitions; the makefile will simplistically auto-generate extern
// declarations for them.)
// All statements in this section should always define a single variable on a
// single line. The makefile will simple-mindedly auto-generate extern
// declarations for them. Don't forget to define (not just declare) constants
// with extern linkage in this section, since C++ global constants have
// internal linkage by default.
//
// End Globals
// Constants
// End Constants
int main(int argc, char* argv[]) {
atexit(teardown);

View File

@ -10,7 +10,8 @@
:(before "End Types")
typedef void (*test_fn)(void);
:(before "End Constants")
:(before "Globals")
// move a global ahead into types that we can't generate an extern declaration for
const test_fn Tests[] = {
#include "test_list" // auto-generated; see makefile
};

View File

@ -92,7 +92,9 @@ bool Hide_errors = false;
Hide_errors = false;
:(before "End Types")
// pre-define some globals that trace_stream needs to know about
// Pre-define some global constants that trace_stream needs to know about.
// Since they're in the Types section, they'll be included in any cleaved
// compilation units. So no extern linkage.
const int Max_depth = 9999;
const int Error_depth = 0; // definitely always print errors
const int App_depth = 2; // temporarily where all mu code will trace to
@ -383,14 +385,14 @@ using std::ofstream;
#include "termbox/termbox.h"
:(before "End Constants")
:(before "End Globals")
//: In future layers we'll use the depth field as follows:
//:
//: Errors will be depth 0.
//: Mu 'applications' will be able to use depths 1-100 as they like.
//: Primitive statements will occupy 101-9989
const int Initial_callstack_depth = 101;
const int Max_callstack_depth = 9989;
extern const int Initial_callstack_depth = 101;
extern const int Max_callstack_depth = 9989;
//: Finally, details of primitive mu statements will occupy depth 9990-9999 (more on that later as well)
//:
//: This framework should help us hide some details at each level, mixing

View File

@ -412,8 +412,8 @@ string_tree* property(const reagent& r, const string& name) {
return NULL;
}
:(before "End Constants")
const string Ignore(","); // commas are ignored in mu except within [] strings
:(before "End Globals")
extern const string Ignore(","); // commas are ignored in mu except within [] strings
:(code)
void skip_whitespace_but_not_newline(istream& in) {
while (true) {

View File

@ -155,9 +155,9 @@ string next_word(istream& in) {
return out.str();
}
:(before "End Constants")
:(before "End Globals")
// word boundaries
const string Terminators("(){}");
extern const string Terminators("(){}");
:(code)
void slurp_word(istream& in, ostream& out) {
char c;

View File

@ -245,7 +245,7 @@ void transform_new_to_allocate(const recipe_ordinal r) {
//: implement 'allocate' based on size
:(before "End Globals")
const int Reserved_for_tests = 1000;
extern const int Reserved_for_tests = 1000;
int Memory_allocated_until = Reserved_for_tests;
int Initial_memory_per_routine = 100000;
:(before "End Setup")

View File

@ -159,6 +159,7 @@ for (int i = 0; i < SIZE(Scenarios); ++i) {
}
:(before "End Globals")
// this isn't a constant, just a global of type const*
const scenario* Current_scenario = NULL;
:(code)
void run_mu_scenario(const scenario& s) {

View File

@ -79,13 +79,13 @@ container foo:t [
]
+error: foo: type ingredient 't' must begin with an underscore
:(before "End Constants")
:(before "End Globals")
// We'll use large type ordinals to mean "the following type of the variable".
// For example, if we have a generic type called foo:_elem, the type
// ingredient _elem in foo's type_info will have value START_TYPE_INGREDIENTS,
// and we'll handle it by looking in the current reagent for the next type
// that appears after foo.
const int START_TYPE_INGREDIENTS = 2000;
extern const int START_TYPE_INGREDIENTS = 2000;
:(before "End Commandline Parsing") // after loading .mu files
assert(Next_type_ordinal < START_TYPE_INGREDIENTS);

View File

@ -133,7 +133,7 @@ $error: 0
//: locations.
:(before "End Globals")
const int Max_variables_in_scenarios = Reserved_for_tests-100;
extern const int Max_variables_in_scenarios = Reserved_for_tests-100;
int Next_predefined_global_for_scenarios = Max_variables_in_scenarios;
:(before "End Setup")
assert(Next_predefined_global_for_scenarios < Reserved_for_tests);
@ -143,10 +143,10 @@ assert(Next_predefined_global_for_scenarios < Reserved_for_tests);
// initialize a default-space.
assert(Name[tmp_recipe.at(0)][""] < Max_variables_in_scenarios);
:(before "End Constants")
// Fixed Scenario Locations.
const int SCREEN = Next_predefined_global_for_scenarios++;
// End Fixed Scenario Locations.
:(before "End Globals")
// Scenario Globals.
extern const int SCREEN = Next_predefined_global_for_scenarios++;
// End Scenario Globals.
//: give 'screen' a fixed location in scenarios
:(before "End Special Scenario Variable Names(r)")

View File

@ -33,8 +33,8 @@ scenario keyboard-in-scenario [
]
]
:(before "End Fixed Scenario Locations")
const int CONSOLE = Next_predefined_global_for_scenarios++;
:(before "End Scenario Globals")
extern const int CONSOLE = Next_predefined_global_for_scenarios++;
//: give 'console' a fixed location in scenarios
:(before "End Special Scenario Variable Names(r)")
Name[r]["console"] = CONSOLE;

View File

@ -72,8 +72,8 @@ scenario assume-filesystem [
]
]
:(before "End Fixed Scenario Locations")
const int FILESYSTEM = Next_predefined_global_for_scenarios++;
:(before "End Globals")
extern const int FILESYSTEM = Next_predefined_global_for_scenarios++;
//: give 'filesystem' a fixed location in scenarios
:(before "End Special Scenario Variable Names(r)")
Name[r]["filesystem"] = FILESYSTEM;