summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Thurston <thurston@colm.net>2016-07-28 18:35:30 -0400
committerAdrian Thurston <thurston@colm.net>2016-07-28 18:35:30 -0400
commitaecca4b68436782235c3e1de7b6bab7a977590b2 (patch)
tree3df2060517f4f88f8919571b95499605111f0808
parent210a0245bf42390f24800e90df0ee8aab10c644d (diff)
downloadcolm-aecca4b68436782235c3e1de7b6bab7a977590b2.tar.gz
implemented a const-string define option -Ename=val
-rw-r--r--src/bytecode.c71
-rw-r--r--src/bytecode.h21
-rw-r--r--src/compiler.h13
-rw-r--r--src/declare.cc77
-rw-r--r--src/main.cc25
-rw-r--r--src/parsetree.h8
-rw-r--r--src/pdarun.c2
-rw-r--r--src/synthesis.cc16
8 files changed, 180 insertions, 53 deletions
diff --git a/src/bytecode.c b/src/bytecode.c
index 12aebf84..4b77399e 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -3635,36 +3635,59 @@ again:
colm_tree_downref( prg, sp, mode );
break;
}
- case IN_GET_STDIN: {
- debug( prg, REALM_BYTECODE, "IN_GET_STDIN\n" );
+ case IN_GET_CONST: {
+ short constValId;
+ read_half( constValId );
- /* Pop the root object. */
- vm_pop_tree();
- if ( prg->stdin_val == 0 )
- prg->stdin_val = colm_stream_open_fd( prg, "<stdin>", 0 );
+ switch ( constValId ) {
+ case IN_CONST_STDIN: {
+ debug( prg, REALM_BYTECODE, "IN_CONST_STDIN\n" );
- vm_push_stream( prg->stdin_val );
- break;
- }
- case IN_GET_STDOUT: {
- debug( prg, REALM_BYTECODE, "IN_GET_STDOUT\n" );
+ /* Pop the root object. */
+ vm_pop_tree();
+ if ( prg->stdin_val == 0 )
+ prg->stdin_val = colm_stream_open_fd( prg, "<stdin>", 0 );
- /* Pop the root object. */
- vm_pop_tree();
- open_stdout( prg );
+ vm_push_stream( prg->stdin_val );
+ break;
+ }
+ case IN_CONST_STDOUT: {
+ debug( prg, REALM_BYTECODE, "IN_CONST_STDOUT\n" );
- vm_push_stream( prg->stdout_val );
- break;
- }
- case IN_GET_STDERR: {
- debug( prg, REALM_BYTECODE, "IN_GET_STDERR\n" );
+ /* Pop the root object. */
+ vm_pop_tree();
+ open_stdout( prg );
- /* Pop the root object. */
- vm_pop_tree();
- if ( prg->stderr_val == 0 )
- prg->stderr_val = colm_stream_open_fd( prg, "<stderr>", 2 );
+ vm_push_stream( prg->stdout_val );
+ break;
+ }
+ case IN_CONST_STDERR: {
+ debug( prg, REALM_BYTECODE, "IN_CONST_STDERR\n" );
+
+ /* Pop the root object. */
+ vm_pop_tree();
+ if ( prg->stderr_val == 0 )
+ prg->stderr_val = colm_stream_open_fd( prg, "<stderr>", 2 );
+
+ vm_push_stream( prg->stderr_val );
+ break;
+ }
+ case IN_CONST_ARG: {
+ word_t offset;
+ read_word( offset );
- vm_push_stream( prg->stderr_val );
+ debug( prg, REALM_BYTECODE, "IN_CONST_ARG %d\n", offset );
+
+ /* Pop the root object. */
+ vm_pop_tree();
+
+ head_t *lit = make_literal( prg, offset );
+ tree_t *tree = construct_string( prg, lit );
+ colm_tree_upref( tree );
+ vm_push_tree( tree );
+ break;
+ }
+ }
break;
}
case IN_SYSTEM: {
diff --git a/src/bytecode.h b/src/bytecode.h
index a4807cef..bba463aa 100644
--- a/src/bytecode.h
+++ b/src/bytecode.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007-2012 Adrian Thurston <thurston@complang.org>
+ * Copyright 2007-2016 Adrian Thurston <thurston@complang.org>
*/
/* This file is part of Colm.
@@ -9,7 +9,9 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * Colm is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Colm is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
@@ -291,9 +293,9 @@ typedef unsigned long colm_value_t;
#define IN_PCR_END_DECK 0xb3
#define IN_OPEN_FILE 0xb4
-#define IN_GET_STDIN 0xb5
-#define IN_GET_STDOUT 0xb6
-#define IN_GET_STDERR 0xb7
+
+#define IN_GET_CONST 0xb5
+
#define IN_TO_UPPER 0xb9
#define IN_TO_LOWER 0xba
@@ -359,6 +361,15 @@ typedef unsigned long colm_value_t;
#define IN_GET_COLLECT_STRING 0x68
/*
+ * Const things to get.
+ */
+#define IN_CONST_STDIN 0x10
+#define IN_CONST_STDOUT 0x11
+#define IN_CONST_STDERR 0x12
+#define IN_CONST_ARG 0x13
+
+
+/*
* IN_FN instructions.
*/
diff --git a/src/compiler.h b/src/compiler.h
index 1888f300..9a45793b 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -79,6 +79,18 @@ struct IncludeStackItem
typedef Vector<IncludeStackItem> IncludeStack;
typedef Vector<const char *> ArgsVector;
+struct DefineArg
+{
+ DefineArg( String name, String value )
+ : name(name), value(value) {}
+
+ String name;
+ String value;
+};
+
+typedef Vector<DefineArg> DefineVector;
+
+extern DefineVector defineArgs;
extern ArgsVector includePaths;
inline long makeReduceCode( long reduction, bool isShiftReduce )
@@ -787,6 +799,7 @@ struct Compiler
void addStderr();
void addArgv();
void addError();
+ void addDefineArgs();
int argvOffset();
int arg0Offset();
void makeDefaultIterators();
diff --git a/src/declare.cc b/src/declare.cc
index ae88d756..6ceffe9d 100644
--- a/src/declare.cc
+++ b/src/declare.cc
@@ -1026,6 +1026,7 @@ void Compiler::declareGlobalFields()
addStderr();
addArgv();
addError();
+ addDefineArgs();
}
void Compiler::addStdin()
@@ -1036,13 +1037,19 @@ void Compiler::addStdin()
/* Create the field and insert it into the map. */
ObjectField *el = ObjectField::cons( internal,
ObjectField::InbuiltFieldType, typeRef, "stdin" );
+
el->isConst = true;
- el->inGetR = IN_GET_STDIN;
- el->inGetWC = IN_GET_STDIN;
- el->inGetWV = IN_GET_STDIN;
- el->inGetValR = IN_GET_STDIN;
- el->inGetValWC = IN_GET_STDIN;
- el->inGetValWV = IN_GET_STDIN;
+
+ el->inGetR = IN_GET_CONST;
+ el->inGetWC = IN_GET_CONST;
+ el->inGetWV = IN_GET_CONST;
+ el->inGetValR = IN_GET_CONST;
+ el->inGetValWC = IN_GET_CONST;
+ el->inGetValWV = IN_GET_CONST;
+
+ el->isConstVal = true;
+ el->constValId = IN_CONST_STDIN;
+
rootNamespace->rootScope->insertField( el->name, el );
}
@@ -1055,13 +1062,17 @@ void Compiler::addStdout()
ObjectField *el = ObjectField::cons( internal,
ObjectField::InbuiltFieldType, typeRef, "stdout" );
el->isConst = true;
- el->inGetR = IN_GET_STDOUT;
- el->inGetWC = IN_GET_STDOUT;
- el->inGetWV = IN_GET_STDOUT;
- el->inGetValR = IN_GET_STDOUT;
- el->inGetValWC = IN_GET_STDOUT;
- el->inGetValWV = IN_GET_STDOUT;
+ el->inGetR = IN_GET_CONST;
+ el->inGetWC = IN_GET_CONST;
+ el->inGetWV = IN_GET_CONST;
+ el->inGetValR = IN_GET_CONST;
+ el->inGetValWC = IN_GET_CONST;
+ el->inGetValWV = IN_GET_CONST;
+
+ el->isConstVal = true;
+ el->constValId = IN_CONST_STDOUT;
+
rootNamespace->rootScope->insertField( el->name, el );
}
@@ -1074,13 +1085,17 @@ void Compiler::addStderr()
ObjectField *el = ObjectField::cons( internal,
ObjectField::InbuiltFieldType, typeRef, "stderr" );
el->isConst = true;
- el->inGetR = IN_GET_STDERR;
- el->inGetWC = IN_GET_STDERR;
- el->inGetWV = IN_GET_STDERR;
- el->inGetValR = IN_GET_STDERR;
- el->inGetValWC = IN_GET_STDERR;
- el->inGetValWV = IN_GET_STDERR;
+ el->inGetR = IN_GET_CONST;
+ el->inGetWC = IN_GET_CONST;
+ el->inGetWV = IN_GET_CONST;
+ el->inGetValR = IN_GET_CONST;
+ el->inGetValWC = IN_GET_CONST;
+ el->inGetValWV = IN_GET_CONST;
+
+ el->isConstVal = true;
+ el->constValId = IN_CONST_STDERR;
+
rootNamespace->rootScope->insertField( el->name, el );
}
@@ -1117,6 +1132,32 @@ void Compiler::addError()
rootNamespace->rootScope->insertField( el->name, el );
}
+void Compiler::addDefineArgs()
+{
+ for ( DefineVector::Iter d = defineArgs; d.lte(); d++ ) {
+ TypeRef *typeRef = TypeRef::cons( internal, uniqueTypeStr );
+
+ /* Create the field and insert it into the map. */
+ ObjectField *el = ObjectField::cons( internal,
+ ObjectField::InbuiltFieldType, typeRef, d->name );
+
+ el->isConst = true;
+
+ el->inGetR = IN_GET_CONST;
+ el->inGetWC = IN_GET_CONST;
+ el->inGetWV = IN_GET_CONST;
+ el->inGetValR = IN_GET_CONST;
+ el->inGetValWC = IN_GET_CONST;
+ el->inGetValWV = IN_GET_CONST;
+
+ el->isConstVal = true;
+ el->constValId = IN_CONST_ARG;
+ el->constValArg = d->value;
+
+ rootNamespace->rootScope->insertField( el->name, el );
+ }
+}
+
void Compiler::initMapFunctions( GenericType *gen )
{
/* Value functions. */
diff --git a/src/main.cc b/src/main.cc
index 703ea8ea..77d29c82 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1,5 +1,5 @@
/*
- * Copyright 2006-2012 Adrian Thurston <thurston@complang.org>
+ * Copyright 2006-2016 Adrian Thurston <thurston@complang.org>
*/
/* This file is part of Colm.
@@ -97,7 +97,8 @@ bool gblLibrary = false;
long gblActiveRealm = 0;
ArgsVector includePaths;
-ArgsVector additionalCodeFiles;;
+DefineVector defineArgs;
+ArgsVector additionalCodeFiles;
/* Print version information. */
void version();
@@ -187,6 +188,7 @@ void usage()
" -x <file> write C++ export code to <file>\n"
" -m <file> write C++ commit code to <file>\n"
" -a <file> additional code file to include in output program\n"
+" -E N=V set a string value availabe in the program\n"
;
}
@@ -194,7 +196,7 @@ void usage()
void version()
{
cout << "Colm version " VERSION << " " PUBDATE << endl <<
- "Copyright (c) 2007-2012 by Adrian D. Thurston" << endl;
+ "Copyright (c) 2007-2016 by Adrian D. Thurston" << endl;
}
/* Scans a string looking for the file extension. If there is a file
@@ -511,7 +513,7 @@ bool inSourceTree( const char *argv0 )
void processArgs( int argc, const char **argv )
{
- ParamCheck pc( "cD:e:x:I:vdlio:S:M:vHh?-:sVa:m:b:", argc, argv );
+ ParamCheck pc( "cD:e:x:I:vdlio:S:M:vHh?-:sVa:m:b:E:", argc, argv );
while ( pc.check() ) {
switch ( pc.state ) {
@@ -595,6 +597,20 @@ void processArgs( int argc, const char **argv )
commitCodeFn = pc.parameterArg;
break;
+ case 'E': {
+ const char *eq = strchr( pc.parameterArg, '=' );
+ if ( eq == 0 )
+ fatal( "-E option argument must contain =" );
+ if ( eq == pc.parameterArg )
+ fatal( "-E variable name is of zero length" );
+
+ defineArgs.append( DefineArg(
+ String( pc.parameterArg, eq-pc.parameterArg ),
+ String( eq + 1 ) ) );
+
+ break;
+ }
+
case 'D':
#if DEBUG
if ( strcmp( pc.parameterArg, "BYTECODE" ) == 0 )
@@ -618,6 +634,7 @@ void processArgs( int argc, const char **argv )
#else
fatal( "-D option specified but debugging messsages not compiled in\n" );
#endif
+ break;
}
break;
diff --git a/src/parsetree.h b/src/parsetree.h
index d1ce46d7..b90cdc8d 100644
--- a/src/parsetree.h
+++ b/src/parsetree.h
@@ -2512,6 +2512,7 @@ struct ObjectField
isConst(false),
refActive(false),
isExport(false),
+ isConstVal(false),
useGenericId(false),
generic(0),
mapKeyField(0),
@@ -2584,10 +2585,17 @@ struct ObjectField
NameScope *scope;
long offset;
bool beenReferenced;
+ /* Declared const. */
bool isConst;
bool refActive;
bool isExport;
+ /* Value is a const thing when that retrieved by the runtime. Requires a
+ * const val id. */
+ bool isConstVal;
+ int constValId;
+ String constValArg;
+
bool useGenericId;
GenericType *generic;
diff --git a/src/pdarun.c b/src/pdarun.c
index 52b203f5..9379ecb3 100644
--- a/src/pdarun.c
+++ b/src/pdarun.c
@@ -2120,7 +2120,7 @@ long colm_parse_loop( program_t *prg, tree_t **sp, struct pda_run *pda_run,
goto skip_send;
}
else {
- debug( prg, REALM_PARSE, "sending an a plain old token: %s\n",
+ debug( prg, REALM_PARSE, "sending a plain old token: %s\n",
prg->rtd->lel_info[pda_run->token_id].name );
/* Is a plain token. */
diff --git a/src/synthesis.cc b/src/synthesis.cc
index 28115dc2..1fb8c17a 100644
--- a/src/synthesis.cc
+++ b/src/synthesis.cc
@@ -430,6 +430,19 @@ UniqueType *LangVarRef::loadField( Compiler *pd, CodeVect &code,
}
}
+ if ( el->isConstVal ) {
+ code.appendHalf( el->constValId );
+
+ if ( el->constValId == IN_CONST_ARG ) {
+ /* Make sure we have this string. */
+ StringMapEl *mapEl = 0;
+ if ( pd->literalStrings.insert( el->constValArg, &mapEl ) )
+ mapEl->value = pd->literalStrings.length()-1;
+
+ code.appendWord( mapEl->value );
+ }
+ }
+
/* If we are dealing with an iterator then dereference it. */
if ( elUT->typeId == TYPE_ITER )
elUT = el->typeRef->searchUniqueType;
@@ -2513,7 +2526,8 @@ void LangStmt::compile( Compiler *pd, CodeVect &code ) const
}
case PrintAccum: {
code.append( IN_LOAD_GLOBAL_R );
- code.append( IN_GET_STDOUT );
+ code.append( IN_GET_CONST );
+ code.appendHalf( IN_CONST_STDOUT );
consItemList->evaluateSendStream( pd, code );
code.append( IN_POP_TREE );
break;