diff options
author | Adrian Thurston <thurston@colm.net> | 2016-07-28 18:35:30 -0400 |
---|---|---|
committer | Adrian Thurston <thurston@colm.net> | 2016-07-28 18:35:30 -0400 |
commit | aecca4b68436782235c3e1de7b6bab7a977590b2 (patch) | |
tree | 3df2060517f4f88f8919571b95499605111f0808 | |
parent | 210a0245bf42390f24800e90df0ee8aab10c644d (diff) | |
download | colm-aecca4b68436782235c3e1de7b6bab7a977590b2.tar.gz |
implemented a const-string define option -Ename=val
-rw-r--r-- | src/bytecode.c | 71 | ||||
-rw-r--r-- | src/bytecode.h | 21 | ||||
-rw-r--r-- | src/compiler.h | 13 | ||||
-rw-r--r-- | src/declare.cc | 77 | ||||
-rw-r--r-- | src/main.cc | 25 | ||||
-rw-r--r-- | src/parsetree.h | 8 | ||||
-rw-r--r-- | src/pdarun.c | 2 | ||||
-rw-r--r-- | src/synthesis.cc | 16 |
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; |