ref: b3d835e235336f8c0e1979fe009eefb24117a169
parent: b623656b7898648e82dcc0adc5c4d03a5ba9b5da
parent: 2bb663c4e88ad3602a2402a039b18a30d7acf556
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Mar 5 08:52:17 EST 2017
Merge branch 'master' of git+ssh://git.eigenstate.org/git/ori/mc
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -193,7 +193,6 @@
return;
}
-
static size_t writebytes(FILE *fd, char *name, size_t off, char *p, size_t sz)
{
size_t i, len;
@@ -216,7 +215,6 @@
return sz;
}
-
static void genstrings(FILE *fd, Htab *strtab)
{
void **k;
@@ -245,7 +243,7 @@
hidden = "";
/* we don't use the stack size directive: myrddin handles
* the stack frobbing on its own */
- fprintf(fd, "TEXT %s%s+0(SB),$0\n", fn->name, hidden);
+ fprintf(fd, "TEXT %s%s+0(SB),2,$0\n", fn->name, hidden);
for (j = 0; j < s->cfg->nbb; j++) {
if (!s->bb[j])
continue;
@@ -359,10 +357,99 @@
writeasm(fd, &is, fn);
}
+static size_t writetextbytes(FILE *fd, char *p, size_t sz)
+{
+ size_t i;
+
+ assert(sz != 0);
+ for (i = 0; i < sz; i++)
+ fprintf(fd, "\tBYTE $%d\n", p[i]);
+
+ return sz;
+}
+
+static size_t encodetextmin(FILE *fd, uvlong val)
+{
+ size_t i, shift, n;
+ uint8_t b;
+
+ if (val < 128) {
+ fprintf(fd, "\tBYTE $%u // single\n", (unsigned)val);
+ return 1;
+ }
+
+ for (i = 1; i < 8; i++)
+ if (val < 1ULL << (7*i))
+ break;
+
+ n = 0;
+ shift = 8 - i;
+ b = ~0ull << (shift + 1);
+ b |= val & ~(~0ull << shift);
+ fprintf(fd, "\tBYTE $%u //first\n", b);
+ val >>= shift;
+ while (val != 0) {
+ n++;
+ fprintf(fd, "BYTE $%llu // tail\n", (uvlong)val & 0xff);
+ val >>= 8;
+ }
+ return i;
+}
+
+static size_t writetextblob(FILE *fd, Blob *b)
+{
+ size_t i, n;
+
+ n = 0;
+ if (!b)
+ return 0;
+ switch (b->type) {
+ case Bti8:
+ fprintf(fd, "\tBYTE $%lld\n", b->ival);
+ n += 1;
+ break;
+ case Bti16:
+ fprintf(fd, "\tSHORT $%lld\n", b->ival);
+ n += 2;
+ break;
+ case Bti32:
+ fprintf(fd, "\tWORD $%lld\n", b->ival);
+ n += 4;
+ break;
+ case Bti64:
+ fprintf(fd, "\tLONG $%lld\n", (vlong)b->ival);
+ n += 8;
+ break;
+ case Btimin:
+ n += encodetextmin(fd, b->ival);
+ break;
+ case Btref:
+ if (b->ref.isextern || b->ref.str[0] == '.')
+ fprintf(fd, "\tLONG $%s+%llu(SB)\n", b->ref.str, (uvlong)b->ref.off);
+ else
+ fprintf(fd, "\tLONG $%s<>+%llu(SB)\n", b->ref.str, (uvlong)b->ref.off);
+ fprintf(fd, "\tLONG $0\n");
+ n += 8;
+ break;
+ case Btbytes:
+ n += writetextbytes(fd, b->bytes.buf, b->bytes.len);
+ break;
+ case Btseq:
+ for (i = 0; i < b->seq.nsub; i++)
+ n += writetextblob(fd, b->seq.sub[i]);
+ break;
+ case Btpad:
+ for (i = 0; i < b->npad; i++)
+ fprintf(fd, "\tBYTE $0\n");
+ n += b->npad;
+ break;
+ }
+ return n;
+}
+
static void gentype(FILE *fd, Type *ty)
{
Blob *b;
- char lbl[1024];
ty = tydedup(ty);
if (ty->type == Tyvar || ty->isemitted)
@@ -372,14 +459,11 @@
b = tydescblob(ty);
if (!b)
return;
- if (b->isglobl) {
- fprintf(fd, "GLOBL %s%s+0(SB),$%llu\n", Symprefix, b->lbl, (uvlong)blobsz(b));
- bprintf(lbl, sizeof lbl, "%s%s", Symprefix, b->lbl);
- } else {
- fprintf(fd, "GLOBL %s%s<>+0(SB),$%llu\n", Symprefix, b->lbl, (uvlong)blobsz(b));
- bprintf(lbl, sizeof lbl, "%s%s<>", Symprefix, b->lbl);
- }
- writeblob(fd, b, 0, lbl);
+ if (b->isglobl)
+ fprintf(fd, "TEXT %s%s+0(SB),2,$0\n", Symprefix, b->lbl);
+ else
+ fprintf(fd, "TEXT %s%s<>+0(SB),2,$0\n", Symprefix, b->lbl);
+ writetextblob(fd, b);
}
static void gentypes(FILE *fd)
--- a/6/main.c
+++ b/6/main.c
@@ -28,6 +28,7 @@
int p9asm;
char *outfile;
char **incpaths;
+char *localincpath;
size_t nincpaths;
Asmsyntax asmsyntax;
@@ -41,7 +42,7 @@
printf("\t-I path\tAdd 'path' to use search path\n");
printf("\t-d\tPrint debug dumps. Recognized options: f r p i\n");
printf("\t-G\tGenerate asm in gas syntax\n");
- printf("\t-8\tGenerate asm in plan 9 syntax\n");
+ printf("\t-9\tGenerate asm in plan 9 syntax\n");
printf("\t-d opts: additional debug logging. Options are listed below:\n");
printf("\t\tf: log folded trees\n");
printf("\t\tl: log lowered pre-cfg trees\n");
@@ -99,6 +100,17 @@
}
}
+static char *dirname(char *path)
+{
+ char *p;
+
+ p = strrchr(path, '/');
+ if (p)
+ return strdupn(path, p - path);
+ else
+ return xstrdup(".");
+}
+
static char *gentempfile(char *buf, size_t bufsz, char *path, char *suffix)
{
char *tmpdir;
@@ -216,11 +228,15 @@
if (ctx.nargs == 0) {
fprintf(stderr, "No input files given\n");
exit(1);
- }
- else if (ctx.nargs > 1)
+ } else if (ctx.nargs > 1)
outfile = NULL;
for (i = 0; i < ctx.nargs; i++) {
+ if (outfile)
+ localincpath = dirname(outfile);
+ else
+ localincpath = dirname(ctx.args[i]);
+
globls = mkstab(0);
tyinit(globls);
tokinit(ctx.args[i]);
@@ -250,6 +266,8 @@
genuse(ctx.args[i]);
gen(file, buf);
assemble(buf, ctx.args[i]);
+
+ free(localincpath);
}
return 0;
--- a/Makefile
+++ b/Makefile
@@ -37,3 +37,6 @@
uninstallmyr:
./mbldwrap.sh uninstall
+
+release:
+ ./support/release.sh 0.1
--- a/README.md
+++ b/README.md
@@ -8,6 +8,19 @@
This combination makes Myrddin suitable for anything ranging from desktop
applications, to embedded systems and potentially even kernel development.
+## Build
+
+Compile with ./configure --prefix="/home/wherever/I/want" && make && make install
+The result will be among other things, the binaries 6m and mbld
+
+## Usage
+
+Compile and execute:
+`mbld -R test.myr`
+
+Compile into a binary:
+`mbld -b binary test.myr`
+
## Examples
A classic:
@@ -77,8 +90,9 @@
## Supported Platforms
Myrddin currently runs on a number of platforms
-- Linux
-- OSX
- FreeBSD
+- Linux
- NetBSD
-- 9front
+- OSX
+- OpenBSD
+- Plan9front
--- a/configure
+++ b/configure
@@ -55,6 +55,7 @@
sysinit='setenv("MACOSX_DEPLOYMENT_TARGET", "10.6", 0)'
echo 'export SYS=osx' >> config.mk
echo export INST_MAN=$prefix/share/man/man >> config.mk
+ echo export MACOSX_DEPLOYMENT_TARGET=10.6 >> config.mk
echo 'const Sys = "OSX"' >> mbld/config.myr
echo 'const Linkcmd = ["ld", ' \
'"-pagezero_size", "0x100000000",' \
--- a/doc/6m.1
+++ b/doc/6m.1
@@ -3,15 +3,14 @@
6m
.SH SYNOPSIS
.B 6m
-.I -[hioS]
+.I -[?hioSG9d]
.I [file...]
.br
.SH DESCRIPTION
.PP
-The ?m family of compilers compile Myrddin source into object files
-for the corresponding architecture. There is one compiler for each
-architecture supported, with a unique name. By default, if the input
-file is named
+The ?m compiler family compiles Myrddin source into object files
+for the corresponding architecture. Each architecture gets its own
+compler. Unless otherwise specified, if the input file is named
.I filename.myr
then the the object file that is generated will be named
.I filename.o.
@@ -22,7 +21,7 @@
.PP
If the filename does not end with the suffix
.I .myr
-then the suffix
+then the object suffix
.I .o
will simply be appended to it.
@@ -36,12 +35,12 @@
The compiler options are:
.TP
-.B -d [flTri]
+.B -d [flTriu]
Print debugging dumps. Additional options may be given to give more
debugging information for specific intermediate states of the compilation.
.TP
-.B -h
+.B -h, -?
Print a summary of the available options.
.TP
@@ -48,16 +47,26 @@
.B -I path
Add 'path' to the search path for unquoted use statments. This option
does not affect the search path for local usefiles, which are always
-searched relative to the compiler's current working directory. Without
+searched relative to the directory containing the output file. Without
any options, the search path defaults to /usr/include/myr.
.TP
.B -o output-file
Specify that the generated code should be placed in
+.I output-file
+instead of the default location.
.TP
.B -S
Generate assembly code along with the object file.
+
+.TP
+.B -G
+Generate assembly in the Gnu As syntax.
+
+.TP
+.B -9
+Generate assembly in the Plan 9 syntax.
.SH EXAMPLE
.EX
--- a/doc/lang.txt
+++ b/doc/lang.txt
@@ -53,7 +53,8 @@
2.1. EBNF-ish:
- Syntax is defined using an informal variant of EBNF.
+ Syntax is defined using an informal variant of EBNF (Extended
+ Backus Naur Form).
token: /regex/ | "quoted" | <informal description>
prod: prodname ":" expr*
@@ -78,10 +79,10 @@
Productions are defined by any number of expressions, in which
expressions are '|' separated sequences of terms.
- Terms can are productions or tokens, and may come with a repeat
- specifier. wrapping a term in "[]" denotes that the term is repeated
- 0 or 1 times. suffixing it with a '*' denotes 0 or more repetitions,
- and '+' denotes 1 or more repetitions.
+ Terms are productions or tokens, and may come with a repeat specifier.
+ wrapping a term in "[]" denotes that the term is repeated 0 or 1
+ times. suffixing it with a '*' denotes 0 or more repetitions, and '+'
+ denotes 1 or more repetitions.
2.2. As-If Rule:
@@ -157,8 +158,8 @@
- Package Definitions:
- These define the list of exported values from a file. As
- part of compilation, all the exported names from a package
+ These define the list of exported symbols from a file. As
+ part of compilation, all the exported symbols from a package
will get merged together from all the files being built
into that package.
@@ -174,14 +175,18 @@
- Trait Definitions:
- These define traits, which are attributes on types that
- may be implemented by impl functions. They define required
- functions on the type.
+ These define traits. Traits are attributes on types that
+ may be implemented by impl statements. They define a
+ constraint that may be set on types passed to generic
+ functions, and the required functions that must be defined
+ by an impl for a type to satisfy that constraint.
- Impl Statements:
- These define implementations of traits, allowing an
- existing trait to be attached to an existing type.
+ These define implementations of traits. Impl statements
+ tag a type as satisfying a trait defined by the constraint,
+ and contain the code needed to implement the requirements
+ imposed by the trait being implemented.
3.3. Declarations:
@@ -191,13 +196,12 @@
declbody: declcore ["=" expr]
declcore: name [":" type]
- A declaration consists of a declaration class (i.e., one
- of 'const', 'var', or 'generic'), followed by a declaration
- name, optionally followed by a type and assignment. One thing
- you may note is that unlike most other languages, there is no
- special function declaration syntax. Instead, a function is
- declared like any other value: by assigning its name to a
- constant or variable.
+ A declaration consists of a declaration class (i.e., one of 'const',
+ 'var', or 'generic'), followed by a declaration name, optionally
+ followed by a type and assignment. It is noteworthy that, unlike most
+ languages, there is no function declaration syntax. Instead, a
+ function is declared like any other symbol: by assigning a function
+ value to a symbol.
const: Declares a constant value, which may not be
modified at run time. Constants must have
@@ -229,6 +233,7 @@
a non-returning function. This attribute is only
valid when applied to a function.
+ The
Examples:
Declare a constant with a value 123. The type is not defined,
@@ -312,8 +317,12 @@
the line where they are declared, if they have an initializer.
Otherwise, their contents are indeterminate. This decision allows for
slightly strange code, but allows for mutually recursive functions
- with no forward declarations or special cases.
+ with no forward declarations or special cases. That is, functions
+ may call each other without regards to order of declaration:
+ const f = {; g() }
+ const g = {; f() }
+
3.5.1. Scope Rules:
Myrddin follows the usual lexical scoping rules. A variable
@@ -335,9 +344,11 @@
3.5.2. Capturing Variables:
- When a closure is created, it captures the stack variables that
- are in its scope by value. This allows for simple heapification of
- the closure.
+ Closures are functions that can refer to variables from their
+ enclosing scopes. When a closure is created, it copies the
+ stack variables that are in scope by value. Global variables are
+ referred to normally. The copying is intended to facilitate moving
+ the closure to the heap with a simple block memory copy.
For example:
@@ -400,13 +411,14 @@
tested for equality, and used in the various boolean operators.
char is a 32 bit integer type, and is guaranteed to hold exactly one
- Unicode codepoint. It can be assigned integer literals, tested
- against, compared, and all the other usual numeric types.
+ Unicode codepoint. It is a numeric type.
The various [u]intN types hold, as expected, signed and unsigned
integers of the named sizes respectively. All arithmetic on them is
done in complement twos of bit size N.
+ Int and uint vary by machine, but are at least 32 bits in size.
+
Similarly, floats hold floating point types with the indicated
precision. They are operated on according to the IEEE754 rules.
@@ -431,9 +443,17 @@
size must be a compile time constant.
If the array size is specified as "...", then the array has zero bytes
- allocated to store it, and bounds are not checked. This is used to
- facilitate flexible arrays at the end of a struct, as well as C ABI.
+ allocated to store it, and bounds are not checked. This allows
+ flexible arrays. Flexible arrays are arrays defined at the end of
+ a struct, which do not contrbute to the size of the array. When
+ allocating a struct on the heap, extra space may be reserved for
+ the array, allowing variable sizes of trailing data. This is not
+ used commonly, but turns out to be useful for C ABI comatibility.
+ Flexible arrays can also be used another way when emulating the C
+ ABI. Myrddin has no tagless unions, but because runs of flexible
+ arrays take zero bytes, a union can be emulated using them.
+
Slices are similar to arrays in many contemporary languages. They are
reference types that store the length of their contents. They are
declared by appending a '[:]' to the base type.
@@ -456,7 +476,7 @@
declared by putting the word 'struct' before a block of declaration
cores (ie, declarations without the storage type specifier).
- Unions are a traditional sum type. The tag defines the value that may
+ Unions are a tag and body pair. The tag defines the value that may
be held by the type at the current time. If the tag has an argument,
then this value may be extracted with a pattern match. Otherwise, only
the tag may be matched against.
@@ -578,9 +598,10 @@
Impls take the interfaces provided by traits, and attach them
to types, as well as providing the concrete implementation of
these types. The declarations are inserted into the global
- namespace, and act identically to generics in.
+ namespace.
- The declarations need not be functions.
+ The declarations need not be functions, and if the types can
+ be appropriately inferred, can define impl specific constants.
4.5. Type Inference:
@@ -601,11 +622,11 @@
When a generic type is encountered, it is freshened. Freshening a
generic type replaces all free type parameters in the type with a
- type variable, inheriting all of the traits.. So, a type '@a' is
+ type variable, inheriting all of the traits. So, a type '@a' is
replaced with the type '$1', and a trait-constrained type
'@a::foo' is replaced with a trait constrained type '$1::foo'.
+ This is also done for subtypes. For example, '@a#' becomes '$t#'
-
Once each leaf expression is assigned a type, a depth first walk
over the tree is done. Each leaf's type is resolved as well as it
can be:
@@ -627,6 +648,44 @@
4.5.2. Unification:
+ The core of type inference is unification. Unification makes
+ two values equal. This proceeds in several cases.
+
+ - If both types being unified are type variables,
+ then the type variables are set to be equal. The
+ set union of the required traits is attached to
+ the type variable.
+
+ - If one type is a type variable, and the other is
+ a concrete type, then the type variable is set to
+ the concrete type. All traits on the type variable
+ must be satisfied.
+
+ - If both types are compatible concrete types, then
+ all subtypes are unfied recursively.
+
+ - If both types are incompatible concrete types, a
+ type error is flagged.
+
+ For example:
+
+ unify($t1, $t2)
+ => we set $t1 = $t2
+
+ unify($t1, int)
+ => we set $t1 = int
+
+ unify(int, int)
+ => success, int is an int
+
+ unify(int, char)
+ => error, char != int
+
+ unify(list($t1), list(int))
+ => list is compatible, so we unify subtypes.
+ $t1 is set to int.
+ success, list($t1) is set to list(int)
+
Once the types of the leaf nodes is initialized, type inference
proceeds via unification. Each expression using the leaves is
checked. The operator type is freshened, and then the expressions
@@ -722,10 +781,10 @@
to be repeated a number of times, although this is rare: Usually
a single pass suffices.
- At this point, default types are applied. An unconstrained type
- with type $t::(numeric,integral) is replaced with int. An
- unconstrained type with $t::(numeric,floating) is replaced with
- flt64.
+ At this point, default types are applied. An unconstrained type
+ with type $t::(numeric,integral) is replaced with int. An
+ unconstrained type with $t::(numeric,floating) is replaced with
+ flt64.
4.6. Built In Traits:
@@ -934,8 +993,9 @@
tupelts: expr ("," expr)* [","]
Sequence literals are used to initialize either a structure
- or an array. They are '['-bracketed expressions, and are evaluated
- Tuple literals are similarly used to initialize a tuple.
+ or an array. Both structure and array literals are bracketed
+ by square brackets. Tuple literals are used to initialize a
+ tuple, and are bracketed by parentheses.
Struct literals describe a fully initialized struct value.
A struct must have at least one member specified, in
@@ -966,7 +1026,7 @@
A tuple literal is a parentheses separated list of values.
A single element tuple contains a trailing comma.
- Example: Struct literal.
+ Example: Struct literal:
[.a = 42, .b="str"]
Example: Array literal:
@@ -983,7 +1043,7 @@
5.1.3. Function Literals:
- funclit: "{" arglist "\n" blockbody "}"
+ funclit: "{" arglist ["->" rettype] "\n" blockbody "}"
arglist: (ident [":" type])*
Function literals describe a function. They begin with a '{',
@@ -1021,9 +1081,10 @@
var b = {; a + 1}
}
- A function literal has the arity of its argument list,
- and shares their type if it is provided. Otherwise,
- they are left generic. The same applies to the return type.
+ A function literal's arity is the same as the number of arguments
+ it takes. The type of the funciton argument list is derived from
+ the type of the arguments. The return type may be provided, or
+ can be left to type inference.
5.1.4: Labels:
@@ -1060,14 +1121,14 @@
For integers, all operations are done in complement twos
arithmetic, with the same bit width as the type being operated on.
For floating point values, the operation is according to the
- IEE754 rules.
+ IEEE754 rules.
The operators are listed below in order of precedence, and a short
- summary of what they do is listed given. For the sake of clarity, 'x'
- will stand in for any expression composed entirely of subexpressions
- with higher precedence than the current current operator. 'e' will
- stand in for any expression. Assignment is right associative. All
- other expressions are left associative.
+ summary of what they do is given. For simplicity, 'x' and 'y' fill
+ in for any expression composed of operators with higher precedence
+ than the operator defined. Similiarly, 'e' will stand in for any
+ valid expression, regardless of precedence. Assignment is right
+ associative. All other expressions are left associative.
Arguments are evaluated in the order of associativity. That is,
if an operator is left associative, then the left hand side of
@@ -1091,7 +1152,7 @@
~x Bitwise negation
+x Positive (no operation)
-x Negate x
- `Tag val Union constructor
+ `Tag val Union constructor
Precedence 9:
x << y Shift left
@@ -1204,13 +1265,13 @@
match, again, given that it is never read from in the body of the
match.
- An represents a location in the machine that can be stored
- to persistently and manipulated by the programmer. An obvious
- example of this would be a variable name, although
-
5.2.4. Cast Expressions:
- Cast expressions convert a value from one type to another.
+ Cast expressions convert a value from one type to another. Some
+ conversions may lose precision, others may convert back and forth
+ without data loss. The former case is referred to as lossy
+ conversion. The latter case is known as round trip conversion.
+
Casting proceeds according to the following rules:
@@ -1310,7 +1371,7 @@
lval = rval, lval <op>= rval
- The assignment operators, group from right to left. These are the
+ The assignment operators group from right to left. These are the
only operators that have right associativity. All of them require
the left operand to be an lvalue. The value of the right hand side
of the expression is stored on the left hand side after this
@@ -1344,7 +1405,7 @@
The `&&` operator returns false if the left hand side evaluates to
false. Otherwise it returns the result of evaluating the lhs. It
- is guaranteed if the rhs is true, the lhs will not be evaluated.
+ is guaranteed if the rhs is false, the lhs will not be evaluated.
The left hand side and right hand side of the expression must
be of the same type. The whole expression evaluates to the type
@@ -1430,7 +1491,7 @@
These operators (+, -) add and subtract their operands. For
integers, all operations are done in complement twos arithmetic,
with the same bit width as the type being operated on. For
- floating point values, the operation is according to the IEE754
+ floating point values, the operation is according to the IEEE754
rules.
Type:
@@ -1591,9 +1652,10 @@
expr[lo:hi], expr[:hi], expr[lo:], expr[:]
- The slice expression produces a sub-slice of the sequence
- or pointer expression being sliced. The elements contained
- in this slice are expr[lo]..expr[hi-1].
+ The slice expression produces a sub-slice of the sequence or
+ pointer expression being sliced. The lower bound is inclusive, and
+ the upper bound is exclusive. The elements contained in this slice
+ are expr[lo]..expr[hi-1].
If the lower bound is omitted, then it is implicitly zero. If the
upper bound is ommitted, then it is implicitly `expr.len`.
@@ -1886,7 +1948,7 @@
toplev: use | pkgdef | decl | traitdef | impldef | tydef
/* packages */
- use: use ident | strlit
+ use: "use" ident | strlit
pkgdef: "pkg" [ident] "=" pkgbody ";;"
pkgbody: (decl | attrs tydef | traitdef | impldef)*
@@ -1909,13 +1971,15 @@
typeid: ident | ident "(" typarams ")"
typarams: typaram ("," typaram)*
type: structdef | uniondef | tupledef |
- compound | generic | "..."
+ constructed | generic | "..."
structdef: "struct" structbody ";;"
+ structbody: declcore*
uniondef: "union" unionbody ";;"
+ unionbody: ("`" ident [type])*
tupledef: "(" type ("," type)* ")"
generic: typaram ["::" traitlist]
traitlist: name | "(" name ("," name)
- compound: functype | sicetype | arraytype | ptrtype | void | name
+ constructed: functype | sicetype | arraytype | ptrtype | void | name
functype: "(" arglist "->" type ")"
arglist: [arg ("," arg)*]
arg: name ":" type
--- a/doc/muse.1
+++ b/doc/muse.1
@@ -3,30 +3,21 @@
muse
.SH SYNOPSIS
.B muse
-.I -[hmidos]
+.I -o out -p pkg [-h] [-d dbg] [-l libs]
.I [file...]
.br
.SH DESCRIPTION
.PP
-The 'muse' tool takes as input a Myrddin source file and generates
-a usefile from it. A usefile collects definitions exported from the
-package specifications in Myrddin source code, and makes them available
-for other programs to include with a 'use' statement.
-.PP
-It can also merge together a number of usefiles into one larger usefile
-including all of the exported symbols. If an output file name is not given,
-and we are not merging usefiles, then an input file named
-.I filename.myr
-will generate a usefile named
-.I filename.use
-\&.
+The muse tool acts as a linker for
+.I .use
+files. It reads all of the usefiles provided to it on the
+command line, filters them by package, and outputs a new
+usefile with the merged set of symbols. Both the
+.I -o out.use
+and the
+.I -p pkg
+options are mandatory.
-If the filename does not end with the suffix
-.I .myr
-then the suffix
-.I .o
-will simply be appended to it.
-
.PP
The output of muse is architecture-independent. However, the format of the
generated file is not stable, and is not guaranteed to work across
@@ -45,26 +36,25 @@
Print a summary of the available options.
.TP
-.B -I path
-Add 'path' to the search path for unquoted use statments. This option
-does not affect the search path for local usefiles, which are always
-searched relative to the compiler's current working directory. Without
-any options, the search path defaults to /usr/include/myr.
+.B -p package
+Take the symbols that match
+.I package
+and their dependencies, and merge them into a single package. Only symbols
+matching the package name will be reexported.
.TP
.B -o output-file
Specify that the generated usefile should be named
+.I output-file.
+By convention,
.I output-file
+should match up with the package name given to the
+.I -p
+option.
-.TP
-.B -s
-Print a summary of the symbols exported from the usefile that is specified.
-
.SH EXAMPLE
.EX
- muse foo.myr
- muse -o bar.use bar-system-version.myr
- muse -mo library foo.use bar.use
+ muse -o library.use -p library foo.use bar.use
.EE
.SH FILES
--- a/lib/crypto/test/md5.myr
+++ b/lib/crypto/test/md5.myr
@@ -1,7 +1,7 @@
use std
use crypto
-use "test/util"
+use "util"
const main = {
hasheq(crypto.md5("")[:], \
--- a/lib/crypto/test/sha1.myr
+++ b/lib/crypto/test/sha1.myr
@@ -1,7 +1,7 @@
use std
use crypto
-use "test/util"
+use "util"
const main = {
hasheq(crypto.sha1("")[:], \
--- a/lib/crypto/test/sha256.myr
+++ b/lib/crypto/test/sha256.myr
@@ -1,7 +1,7 @@
use std
use crypto
-use "test/util"
+use "util"
const main = {
hasheq(crypto.sha224("")[:], \
--- a/lib/crypto/test/sha512.myr
+++ b/lib/crypto/test/sha512.myr
@@ -1,7 +1,7 @@
use std
use crypto
-use "test/util"
+use "util"
const main = {
hasheq(crypto.sha384("")[:], \
--- a/lib/json/test/parse.myr
+++ b/lib/json/test/parse.myr
@@ -125,7 +125,7 @@
std.put("ignoring implementation defined test {}\n", f)
| wat:
if !std.sleq(f, "LICENSE")
- std.fatal("unknown test {}: needs to start with y or n\n", f)
+ std.fatal("unknown test '{}': needs to start with y or n\n", f)
;;
;;
std.slfree(data)
--- a/lib/std/syswrap+plan9.myr
+++ b/lib/std/syswrap+plan9.myr
@@ -77,16 +77,26 @@
/* statbuf offsets */
pkglocal const Sizeoff : int64 = 0
- pkglocal const Typeoff : int64 = 2
- pkglocal const Devoff : int64 = 4
- pkglocal const Qidtypeoff : int64 =8
- pkglocal const Qidversoff : int64 = 9
- pkglocal const Qidpathoff : int64 = 13
- pkglocal const Modeoff : int64 = 21
- pkglocal const Atimeoff : int64 = 25
- pkglocal const Mtimeoff : int64 = 29
- pkglocal const Lengthoff : int64 = 31
- pkglocal const Stringsoff : int64 = 39
+ pkglocal const Sizesz : int64 = 2
+ pkglocal const Typeoff : int64 = Sizeoff + Sizesz
+ pkglocal const Typesz : int64 = 2
+ pkglocal const Devoff : int64 = Typeoff + Typesz
+ pkglocal const Devsz : int64 = 4
+ pkglocal const Qidtypeoff : int64 = Devoff + Devsz
+ pkglocal const Qidtypesz : int64 = 1
+ pkglocal const Qidversoff : int64 = Qidtypeoff + Qidtypesz
+ pkglocal const Qidverssz : int64 = 4
+ pkglocal const Qidpathoff : int64 = Qidversoff + Qidverssz
+ pkglocal const Qidpathsz : int64 = 8
+ pkglocal const Modeoff : int64 = Qidpathoff + Qidpathsz
+ pkglocal const Modesz : int64 = 4
+ pkglocal const Atimeoff : int64 = Modeoff + Modesz
+ pkglocal const Atimesz : int64 = 4
+ pkglocal const Mtimeoff : int64 = Atimeoff + Atimesz
+ pkglocal const Mtimesz : int64 = 4
+ pkglocal const Lengthoff : int64 = Mtimeoff + Mtimesz
+ pkglocal const Lengthsz : int64 = 8
+ pkglocal const Stringsoff : int64 = Lengthoff + Lengthsz
;;
/* UGLY: circular dependency breaking... */
--- a/lib/std/test/fltbits.myr
+++ b/lib/std/test/fltbits.myr
@@ -1,5 +1,5 @@
use std
const main = {
- std.assert(std.isnan(0./0.), "isnan(0/0) false\n")
+ std.assert(std.isnan(std.flt64nan()), "isnan(nan) false\n")
}
--- a/lib/sys/sys+openbsd-x64.myr
+++ b/lib/sys/sys+openbsd-x64.myr
@@ -1,4 +1,4 @@
-use "systypes.use"
+use "systypes"
pkg sys =
type pid = int32 /* process id */
--- a/lib/thread/bld.sub
+++ b/lib/thread/bld.sub
@@ -18,10 +18,10 @@
# netbsd impl of thread primitives
#condvar+netbsd.myr
- mutex+netbsd.myr
- spawn+netbsd.myr
- ncpu+netbsd.myr
- exit+netbsd-x64.s
+ #mutex+netbsd.myr
+ #spawn+netbsd.myr
+ #ncpu+netbsd.myr
+ #exit+netbsd-x64.s
# osx impl of thread primitives
#condvar+osx.myr
@@ -38,7 +38,6 @@
# openbsd impl of thread primitives
spawn+openbsd.myr
exit+openbsd-x64.s
-
atomic-impl+x64.s
atomic.myr
--- a/lib/thread/condvar+freebsd.myr
+++ b/lib/thread/condvar+freebsd.myr
@@ -1,9 +1,9 @@
use std
use sys
-use "atomic.use"
-use "common.use"
-use "mutex.use"
+use "atomic"
+use "common"
+use "mutex"
pkg thread =
type cond = struct
--- a/lib/thread/condvar+linux.myr
+++ b/lib/thread/condvar+linux.myr
@@ -1,9 +1,9 @@
use std
use sys
-use "atomic.use"
-use "common.use"
-use "mutex.use"
+use "atomic"
+use "common"
+use "mutex"
pkg thread =
type cond = struct
--- a/lib/thread/future.myr
+++ b/lib/thread/future.myr
@@ -1,6 +1,6 @@
use std
-use "mutex.use"
+use "mutex"
pkg thread =
type future(@a) = struct
--- a/lib/thread/mutex+freebsd.myr
+++ b/lib/thread/mutex+freebsd.myr
@@ -1,8 +1,8 @@
use std
use sys
-use "atomic.use"
-use "common.use"
+use "atomic"
+use "common"
pkg thread =
type mutex = struct
--- a/lib/thread/mutex+linux.myr
+++ b/lib/thread/mutex+linux.myr
@@ -1,8 +1,8 @@
use std
use sys
-use "atomic.use"
-use "common.use"
+use "atomic"
+use "common"
pkg thread =
type mutex = struct
--- a/lib/thread/mutex+plan9.myr
+++ b/lib/thread/mutex+plan9.myr
@@ -2,8 +2,8 @@
use sys
-use "atomic.use"
-use "common.use"
+use "atomic"
+use "common"
pkg thread =
type mutex = struct
--- a/lib/thread/mutex.myr
+++ b/lib/thread/mutex.myr
@@ -2,8 +2,8 @@
use sys
-use "atomic.use"
-use "common.use"
+use "atomic"
+use "common"
pkg thread =
type mutex = struct
--- a/lib/thread/test/atomic.myr
+++ b/lib/thread/test/atomic.myr
@@ -1,7 +1,7 @@
use std
use thread
-use "test/util.use"
+use "util"
const Nherd = 20
--- a/lib/thread/test/condvar.myr
+++ b/lib/thread/test/condvar.myr
@@ -1,7 +1,7 @@
use std
use thread
-use "test/util.use"
+use "util"
const Nwakes = 1000
--- a/lib/thread/test/future.myr
+++ b/lib/thread/test/future.myr
@@ -2,7 +2,7 @@
use sys
use thread
-use "test/util.use"
+use "util"
var fut
var nready : int32
--- a/lib/thread/test/mutex.myr
+++ b/lib/thread/test/mutex.myr
@@ -1,7 +1,7 @@
use std
use thread
-use "test/util.use"
+use "util"
const Nherd = 20
--- a/mbld/deps.myr
+++ b/mbld/deps.myr
@@ -148,7 +148,7 @@
;;
std.exit(1)
;;
- deps = getdeps(b, ds, path)
+ deps = getdeps(b, ds, path, std.dirname(path))
std.htput(g.seen, path, true)
for d in deps
match d
@@ -253,7 +253,7 @@
-> (cflags, libs)
}
-const getdeps = {b, ds, path
+const getdeps = {b, ds, path, dir
var deps, lnum
var f
@@ -266,7 +266,7 @@
| `bio.Err e: std.fatal("unable to read {}: {}\n", path, e)
| `bio.Eof: break
| `bio.Ok ln:
- deps = depname(deps, ln, lnum)
+ deps = depname(deps, ln, lnum, dir)
std.slfree(ln)
;;
;;
@@ -288,7 +288,9 @@
;;
}
-const depname = {deps, ln, lnum
+const depname = {deps, ln, lnum, dir
+ var p
+
/*
the regex pattern does some contortions to either grab
an unquoted path and put it into uses[4], or a quoted
@@ -299,7 +301,8 @@
if uses[2].len > 0
std.slpush(&deps, `Lib (std.sldup(uses[2]), lnum))
else
- std.slpush(&deps, `Local (std.sldup(uses[3]), lnum))
+ p = std.pathcat(dir, std.sldup(uses[3]))
+ std.slpush(&deps, `Local (p, lnum))
;;
regex.matchfree(uses)
| `std.None:
--- a/mbld/util.myr
+++ b/mbld/util.myr
@@ -59,22 +59,27 @@
}
const srcsplit = {src
- var platf, suff
+ var platf, fbase, suff
platf = ""
suff = ""
- match std.strfind(src, ".")
+
+ match std.strfind(src, "/")
+ | `std.Some i: fbase = i
+ | `std.None: fbase = 0
+ ;;
+ match std.strfind(src[fbase:], ".")
| `std.Some i:
- suff = src[i:]
- src = src[:i]
+ suff = src[fbase+i:]
+ src = src[:fbase+i]
| `std.None:
/* no suffix to trim */
;;
- match std.strrfind(src, "+")
+ match std.strrfind(src[fbase:], "+")
| `std.Some i:
- platf = src[i:]
- src = src[:i]
+ platf = src[fbase+i:]
+ src = src[:fbase+i]
| `std.None:
/* no platform to trim */
;;
--- a/mk/bootstrap/bootstrap+Darwin-x86_64.sh
+++ b/mk/bootstrap/bootstrap+Darwin-x86_64.sh
@@ -7,10 +7,11 @@
echo $pwd/6/6m syserrno+osx.myr && $pwd/6/6m syserrno+osx.myr &&\
echo $pwd/6/6m systypes.myr && $pwd/6/6m systypes.myr &&\
echo $pwd/6/6m sys+osx-x64.myr && $pwd/6/6m sys+osx-x64.myr &&\
+echo $pwd/6/6m setup+posixy.myr && $pwd/6/6m setup+posixy.myr &&\
echo as -g -o syscall.o syscall+osx-x64.s && as -g -o syscall.o syscall+osx-x64.s &&\
echo $pwd/6/6m ifreq+osx.myr && $pwd/6/6m ifreq+osx.myr &&\
-echo $pwd/muse/muse -o libsys.use -p sys syserrno.use sys.use systypes.use ifreq.use && $pwd/muse/muse -o libsys.use -p sys syserrno.use sys.use systypes.use ifreq.use &&\
-echo ar -rcs libsys.a syserrno.o syscall.o util.o sys.o systypes.o ifreq.o && ar -rcs libsys.a syserrno.o syscall.o util.o sys.o systypes.o ifreq.o &&\
+echo $pwd/muse/muse -o libsys.use -p sys syserrno.use sys.use setup.use systypes.use ifreq.use && $pwd/muse/muse -o libsys.use -p sys syserrno.use sys.use setup.use systypes.use ifreq.use &&\
+echo ar -rcs libsys.a syserrno.o syscall.o util.o sys.o setup.o systypes.o ifreq.o && ar -rcs libsys.a syserrno.o syscall.o util.o sys.o setup.o systypes.o ifreq.o &&\
echo cd $pwd/lib/std && cd $pwd/lib/std &&\
echo $pwd/6/6m -I ../sys -I . types.myr && $pwd/6/6m -I ../sys -I . types.myr &&\
echo $pwd/6/6m -I ../sys -I . cstrconv.myr && $pwd/6/6m -I ../sys -I . cstrconv.myr &&\
@@ -62,6 +63,8 @@
echo $pwd/6/6m -I ../sys -I . readall.myr && $pwd/6/6m -I ../sys -I . readall.myr &&\
echo $pwd/6/6m -I ../sys -I . slurp.myr && $pwd/6/6m -I ../sys -I . slurp.myr &&\
echo $pwd/6/6m -I ../sys -I . dirname.myr && $pwd/6/6m -I ../sys -I . dirname.myr &&\
+echo $pwd/6/6m -I ../sys -I . chomp.myr && $pwd/6/6m -I ../sys -I . chomp.myr &&\
+echo $pwd/6/6m -I ../sys -I . fltparse.myr && $pwd/6/6m -I ../sys -I . fltparse.myr &&\
echo $pwd/6/6m -I ../sys -I . optparse.myr && $pwd/6/6m -I ../sys -I . optparse.myr &&\
echo $pwd/6/6m -I ../sys -I . dir+osx.myr && $pwd/6/6m -I ../sys -I . dir+osx.myr &&\
echo $pwd/6/6m -I ../sys -I . ipparse.myr && $pwd/6/6m -I ../sys -I . ipparse.myr &&\
@@ -73,16 +76,15 @@
echo $pwd/6/6m -I ../sys -I . env+posixy.myr && $pwd/6/6m -I ../sys -I . env+posixy.myr &&\
echo $pwd/6/6m -I ../sys -I . execvp.myr && $pwd/6/6m -I ../sys -I . execvp.myr &&\
echo $pwd/6/6m -I ../sys -I . slput.myr && $pwd/6/6m -I ../sys -I . slput.myr &&\
+echo $pwd/6/6m -I ../sys -I . wait+posixy.myr && $pwd/6/6m -I ../sys -I . wait+posixy.myr &&\
echo $pwd/6/6m -I ../sys -I . spork.myr && $pwd/6/6m -I ../sys -I . spork.myr &&\
echo $pwd/6/6m -I ../sys -I . getint.myr && $pwd/6/6m -I ../sys -I . getint.myr &&\
echo $pwd/6/6m -I ../sys -I . blat.myr && $pwd/6/6m -I ../sys -I . blat.myr &&\
echo $pwd/6/6m -I ../sys -I . diriter.myr && $pwd/6/6m -I ../sys -I . diriter.myr &&\
echo $pwd/6/6m -I ../sys -I . clear.myr && $pwd/6/6m -I ../sys -I . clear.myr &&\
-echo $pwd/6/6m -I ../sys -I . wait+posixy.myr && $pwd/6/6m -I ../sys -I . wait+posixy.myr &&\
echo $pwd/6/6m -I ../sys -I . strjoin.myr && $pwd/6/6m -I ../sys -I . strjoin.myr &&\
echo $pwd/6/6m -I ../sys -I . pathjoin.myr && $pwd/6/6m -I ../sys -I . pathjoin.myr &&\
echo $pwd/6/6m -I ../sys -I . mktemp.myr && $pwd/6/6m -I ../sys -I . mktemp.myr &&\
-echo $pwd/6/6m -I ../sys -I . chomp.myr && $pwd/6/6m -I ../sys -I . chomp.myr &&\
echo as -g -o memops-impl.o memops-impl+posixy-x64.s && as -g -o memops-impl.o memops-impl+posixy-x64.s &&\
echo $pwd/6/6m -I ../sys -I . fndup.myr && $pwd/6/6m -I ../sys -I . fndup.myr &&\
echo $pwd/6/6m -I ../sys -I . mkpath.myr && $pwd/6/6m -I ../sys -I . mkpath.myr &&\
@@ -99,8 +101,8 @@
echo $pwd/6/6m -I ../sys -I . swap.myr && $pwd/6/6m -I ../sys -I . swap.myr &&\
echo $pwd/6/6m -I ../sys -I . sjlj.myr && $pwd/6/6m -I ../sys -I . sjlj.myr &&\
echo $pwd/6/6m -I ../sys -I . dial+posixy.myr && $pwd/6/6m -I ../sys -I . dial+posixy.myr &&\
-echo $pwd/muse/muse -o libstd.use -p std dial.use fmtfuncs.use fmt.use try.use pathjoin.use strjoin.use sljoin.use slpush.use strstrip.use htab.use now.use getcwd.use rand.use dir.use slurp.use varargs.use listen.use strbuf.use clear.use slput.use strsplit.use introspect.use mktemp.use alloc.use optparse.use memops.use bytealloc.use fltbits.use striter.use sldup.use fltfmt.use extremum.use option.use errno.use wait.use slcp.use writeall.use putint.use consts.use syswrap.use sleep.use readall.use sort.use blat.use diriter.use sjlj.use backtrace.use mk.use swap.use hassuffix.use execvp.use ipparse.use types.use slpop.use strfind.use utf.use dialparse.use syswrap-ss.use cstrconv.use die.use units.use search.use result.use bitset.use env.use resolve.use intparse.use hasprefix.use mkpath.use getint.use dirname.use sleq.use endian.use iterutil.use spork.use assert.use cmp.use chartype.use bigint.use hashfuncs.use slfill.use threadhooks.use fndup.use chomp.use && $pwd/muse/muse -o libstd.use -p std dial.use fmtfuncs.use fmt.use try.use pathjoin.use strjoin.use sljoin.use slpush.use strstrip.use htab.use now.use getcwd.use rand.use dir.use slurp.use varargs.use listen.use strbuf.use clear.use slput.use strsplit.use introspect.use mktemp.use alloc.use optparse.use memops.use bytealloc.use fltbits.use striter.use sldup.use fltfmt.use extremum.use option.use errno.use wait.use slcp.use writeall.use putint.use consts.use syswrap.use sleep.use readall.use sort.use blat.use diriter.use sjlj.use backtrace.use mk.use swap.use hassuffix.use execvp.use ipparse.use types.use slpop.use strfind.use utf.use dialparse.use syswrap-ss.use cstrconv.use die.use units.use search.use result.use bitset.use env.use resolve.use intparse.use hasprefix.use mkpath.use getint.use dirname.use sleq.use endian.use iterutil.use spork.use assert.use cmp.use chartype.use bigint.use hashfuncs.use slfill.use threadhooks.use fndup.use chomp.use &&\
-echo ar -rcs libstd.a dial.o fmtfuncs.o fmt.o try.o pathjoin.o strjoin.o memops-impl.o sljoin.o slpush.o strstrip.o htab.o now.o getbp.o getcwd.o rand.o dir.o slurp.o varargs.o listen.o strbuf.o clear.o slput.o strsplit.o introspect.o mktemp.o alloc.o optparse.o memops.o bytealloc.o fltbits.o striter.o sldup.o fltfmt.o extremum.o option.o errno.o wait.o slcp.o writeall.o putint.o consts.o syswrap.o sleep.o readall.o sort.o blat.o diriter.o sjlj.o backtrace.o mk.o swap.o hassuffix.o execvp.o ipparse.o types.o slpop.o strfind.o utf.o dialparse.o syswrap-ss.o cstrconv.o die.o units.o search.o result.o bitset.o env.o resolve.o intparse.o hasprefix.o mkpath.o getint.o dirname.o sleq.o endian.o iterutil.o spork.o assert.o cmp.o sjlj-impl.o chartype.o bigint.o hashfuncs.o slfill.o threadhooks.o fndup.o chomp.o && ar -rcs libstd.a dial.o fmtfuncs.o fmt.o try.o pathjoin.o strjoin.o memops-impl.o sljoin.o slpush.o strstrip.o htab.o now.o getbp.o getcwd.o rand.o dir.o slurp.o varargs.o listen.o strbuf.o clear.o slput.o strsplit.o introspect.o mktemp.o alloc.o optparse.o memops.o bytealloc.o fltbits.o striter.o sldup.o fltfmt.o extremum.o option.o errno.o wait.o slcp.o writeall.o putint.o consts.o syswrap.o sleep.o readall.o sort.o blat.o diriter.o sjlj.o backtrace.o mk.o swap.o hassuffix.o execvp.o ipparse.o types.o slpop.o strfind.o utf.o dialparse.o syswrap-ss.o cstrconv.o die.o units.o search.o result.o bitset.o env.o resolve.o intparse.o hasprefix.o mkpath.o getint.o dirname.o sleq.o endian.o iterutil.o spork.o assert.o cmp.o sjlj-impl.o chartype.o bigint.o hashfuncs.o slfill.o threadhooks.o fndup.o chomp.o &&\
+echo $pwd/muse/muse -o libstd.use -p std dial.use fmtfuncs.use fmt.use try.use pathjoin.use strjoin.use sljoin.use slpush.use strstrip.use htab.use now.use getcwd.use rand.use dir.use slurp.use varargs.use listen.use strbuf.use clear.use slput.use strsplit.use introspect.use mktemp.use alloc.use optparse.use memops.use bytealloc.use fltbits.use striter.use sldup.use fltfmt.use extremum.use option.use errno.use wait.use slcp.use writeall.use putint.use consts.use syswrap.use sleep.use readall.use sort.use blat.use diriter.use sjlj.use fltparse.use backtrace.use mk.use swap.use hassuffix.use execvp.use ipparse.use types.use slpop.use strfind.use utf.use dialparse.use syswrap-ss.use cstrconv.use die.use units.use search.use result.use bitset.use env.use resolve.use intparse.use hasprefix.use mkpath.use getint.use dirname.use sleq.use endian.use iterutil.use spork.use assert.use cmp.use chartype.use bigint.use hashfuncs.use slfill.use threadhooks.use fndup.use chomp.use && $pwd/muse/muse -o libstd.use -p std dial.use fmtfuncs.use fmt.use try.use pathjoin.use strjoin.use sljoin.use slpush.use strstrip.use htab.use now.use getcwd.use rand.use dir.use slurp.use varargs.use listen.use strbuf.use clear.use slput.use strsplit.use introspect.use mktemp.use alloc.use optparse.use memops.use bytealloc.use fltbits.use striter.use sldup.use fltfmt.use extremum.use option.use errno.use wait.use slcp.use writeall.use putint.use consts.use syswrap.use sleep.use readall.use sort.use blat.use diriter.use sjlj.use fltparse.use backtrace.use mk.use swap.use hassuffix.use execvp.use ipparse.use types.use slpop.use strfind.use utf.use dialparse.use syswrap-ss.use cstrconv.use die.use units.use search.use result.use bitset.use env.use resolve.use intparse.use hasprefix.use mkpath.use getint.use dirname.use sleq.use endian.use iterutil.use spork.use assert.use cmp.use chartype.use bigint.use hashfuncs.use slfill.use threadhooks.use fndup.use chomp.use &&\
+echo ar -rcs libstd.a dial.o fmtfuncs.o fmt.o try.o pathjoin.o strjoin.o memops-impl.o sljoin.o slpush.o strstrip.o htab.o now.o getbp.o getcwd.o rand.o dir.o slurp.o varargs.o listen.o strbuf.o clear.o slput.o strsplit.o introspect.o mktemp.o alloc.o optparse.o memops.o bytealloc.o fltbits.o striter.o sldup.o fltfmt.o extremum.o option.o errno.o wait.o slcp.o writeall.o putint.o consts.o syswrap.o sleep.o readall.o sort.o blat.o diriter.o sjlj.o fltparse.o backtrace.o mk.o swap.o hassuffix.o execvp.o ipparse.o types.o slpop.o strfind.o utf.o dialparse.o syswrap-ss.o cstrconv.o die.o units.o search.o result.o bitset.o env.o resolve.o intparse.o hasprefix.o mkpath.o getint.o dirname.o sleq.o endian.o iterutil.o spork.o assert.o cmp.o sjlj-impl.o chartype.o bigint.o hashfuncs.o slfill.o threadhooks.o fndup.o chomp.o && ar -rcs libstd.a dial.o fmtfuncs.o fmt.o try.o pathjoin.o strjoin.o memops-impl.o sljoin.o slpush.o strstrip.o htab.o now.o getbp.o getcwd.o rand.o dir.o slurp.o varargs.o listen.o strbuf.o clear.o slput.o strsplit.o introspect.o mktemp.o alloc.o optparse.o memops.o bytealloc.o fltbits.o striter.o sldup.o fltfmt.o extremum.o option.o errno.o wait.o slcp.o writeall.o putint.o consts.o syswrap.o sleep.o readall.o sort.o blat.o diriter.o sjlj.o fltparse.o backtrace.o mk.o swap.o hassuffix.o execvp.o ipparse.o types.o slpop.o strfind.o utf.o dialparse.o syswrap-ss.o cstrconv.o die.o units.o search.o result.o bitset.o env.o resolve.o intparse.o hasprefix.o mkpath.o getint.o dirname.o sleq.o endian.o iterutil.o spork.o assert.o cmp.o sjlj-impl.o chartype.o bigint.o hashfuncs.o slfill.o threadhooks.o fndup.o chomp.o &&\
echo cd $pwd/lib/regex && cd $pwd/lib/regex &&\
echo $pwd/6/6m -I ../std -I ../sys types.myr && $pwd/6/6m -I ../std -I ../sys types.myr &&\
echo $pwd/6/6m -I ../std -I ../sys interp.myr && $pwd/6/6m -I ../std -I ../sys interp.myr &&\
--- a/muse/muse.c
+++ b/muse/muse.c
@@ -25,6 +25,7 @@
size_t nincpaths;
char **extralibs;
size_t nextralibs;
+char *localincpath;
static void usage(char *prog)
{
@@ -31,7 +32,6 @@
printf("%s [-hIdos] [-o outfile] [-p pkgname] [-m] inputs\n", prog);
printf("\t-h\tprint this help\n");
printf("\t\tThe outfile must be the same name as each package merged.\n");
- printf("\t-I path\tAdd 'path' to use search path\n");
printf("\t-d\tPrint debug dumps\n");
printf("\t-o out\tOutput to outfile\n");
printf("\t-s\tShow the contents of usefiles `inputs`\n");
@@ -56,7 +56,8 @@
size_t i;
FILE *f;
- optinit(&ctx, "sd:hmo:p:I:l:", argv, argc);
+ localincpath = ".";
+ optinit(&ctx, "sd:hmo:p:l:", argv, argc);
while (!optdone(&ctx)) {
switch (optnext(&ctx)) {
case 'h':
@@ -73,15 +74,9 @@
while (ctx.optarg && *ctx.optarg)
debugopt[*ctx.optarg++ & 0x7f] = 1;
break;
- case 'I':
- lappend(&incpaths, &nincpaths, ctx.optarg);
- break;
case 'l':
lappend(&extralibs, &nextralibs, ctx.optarg);
break;
- case 's':
- show = 1;
- break;
default:
usage(argv[0]);
exit(0);
@@ -89,13 +84,14 @@
}
}
- lappend(&incpaths, &nincpaths, Instroot "/lib/myr");
- if (!outfile) {
+ if (!outfile && !show) {
fprintf(stderr, "output file needed when merging usefiles.\n");
exit(1);
}
- if (!pkgname)
- pkgname = outfile;
+ if (!pkgname) {
+ fprintf(stderr, "package needed when merging usefiles.\n");
+ exit(1);
+ }
/* read and parse the file */
file = mkfile("internal");
@@ -110,10 +106,7 @@
/* generate the usefile */
f = fopen(outfile, "w");
- if (debugopt['s'] || show)
- dumpstab(file->file.globls, stdout);
- else
- writeuse(f, file);
+ writeuse(f, file);
fclose(f);
return 0;
}
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -287,7 +287,7 @@
;
decllist: declbody {
- $$.nl = NULL; $$.nn = 0;
+ $$.loc = $1->loc; $$.nl = NULL; $$.nn = 0;
lappend(&$$.nl, &$$.nn, $1);
}
| declbody Tcomma decllist {
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -559,5 +559,6 @@
extern char *outfile;
extern char **incpaths;
extern size_t nincpaths;
+extern char *localincpath;
void yyerror(const char *s);
--- a/parse/use.c
+++ b/parse/use.c
@@ -1031,18 +1031,18 @@
char *t, *p;
char buf[512];
- /* local (quoted) uses are always relative to the cwd */
+ /* local (quoted) uses are always relative to the output */
fd = NULL;
p = NULL;
if (use->use.islocal) {
- if (hassuffix(use->use.name, ".use"))
- snprintf(buf, sizeof buf, "%s", use->use.name);
- else
- snprintf(buf,sizeof buf, "%s.use", use->use.name);
-
+ snprintf(buf,sizeof buf, "%s/%s.use", localincpath, use->use.name);
p = strdup(buf);
fd = fopen(p, "r");
- /* nonlocal (barename) uses are always searched on the include path */
+ if (!fd) {
+ fprintf(stderr, "could not open usefile %s\n", buf);
+ exit(1);
+ }
+ /* nonlocal (barename) uses are always searched on the include path */
} else {
for (i = 0; i < nincpaths; i++) {
snprintf(buf, sizeof buf, "lib%s.use", use->use.name);
@@ -1064,12 +1064,12 @@
}
free(p);
}
- }
- if (!fd) {
- fprintf(stderr, "could not open usefile %s in search path:\n", use->use.name);
- for (i = 0; i < nincpaths; i++)
- fprintf(stderr, "\t%s\n", incpaths[i]);
- exit(1);
+ if (!fd) {
+ fprintf(stderr, "could not open usefile %s in search path:\n", use->use.name);
+ for (i = 0; i < nincpaths; i++)
+ fprintf(stderr, "\t%s\n", incpaths[i]);
+ exit(1);
+ }
}
if (!loaduse(p, fd, st, vis))
--- /dev/null
+++ b/support/release.sh
@@ -1,0 +1,26 @@
+#!/bin/sh
+set -e
+set -x
+
+tmp=/tmp/myr-release
+rm -rf $tmp
+mkdir -p $tmp
+cp -r ../mc $tmp/
+(
+ cd $tmp/mc
+ git clean -xfd
+ rm -rf .git
+)
+
+(
+ cd $tmp
+ tar cvf myrddin-$1.tar mc
+ bzip2 myrddin-$1.tar
+ tar cvf myrddin-$1.tar mc
+ gzip myrddin-$1.tar
+ tar cvf myrddin-$1.tar mc
+ xz myrddin-$1.tar
+)
+
+cp $tmp/myrddin-$1.tar.* .
+
--- a/util/util.c
+++ b/util/util.c
@@ -24,6 +24,16 @@
return ret;
}
+char *xstrdup(char *s)
+{
+ char *p;
+
+ p = strdup(s);
+ if (!p && s)
+ die("Out of memory");
+ return p;
+}
+
char *strjoin(char *u, char *v)
{
size_t n;
--- a/util/util.h
+++ b/util/util.h
@@ -121,6 +121,7 @@
void *xrealloc(void *p, size_t size);
void die(char *msg, ...) FATAL;
char *strdupn(char *s, size_t len);
+char *xstrdup(char *s);
char *strjoin(char *u, char *v);
void *memdup(void *mem, size_t len);
size_t bprintf(char *buf, size_t len, char *fmt, ...);