summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-03-05 13:52:17 -0800
committerOri Bernstein <ori@eigenstate.org>2017-03-05 13:54:27 -0800
commitb3d835e235336f8c0e1979fe009eefb24117a169 (patch)
tree67bcc668d9e2b2c521e2872908d529ce60c2b2d4
parentb623656b7898648e82dcc0adc5c4d03a5ba9b5da (diff)
parent2bb663c4e88ad3602a2402a039b18a30d7acf556 (diff)
downloadmc-b3d835e235336f8c0e1979fe009eefb24117a169.tar.gz
Merge branch 'master' of git+ssh://git.eigenstate.org/git/ori/mc
-rw-r--r--6/genp9.c108
-rw-r--r--6/main.c24
-rw-r--r--Makefile3
-rw-r--r--README.md20
-rwxr-xr-xconfigure1
-rw-r--r--doc/6m.127
-rw-r--r--doc/lang.txt192
-rw-r--r--doc/muse.152
-rw-r--r--lib/crypto/test/md5.myr2
-rw-r--r--lib/crypto/test/sha1.myr2
-rw-r--r--lib/crypto/test/sha256.myr2
-rw-r--r--lib/crypto/test/sha512.myr2
-rw-r--r--lib/json/test/parse.myr2
-rw-r--r--lib/std/syswrap+plan9.myr30
-rw-r--r--lib/std/test/fltbits.myr2
-rw-r--r--lib/sys/sys+openbsd-x64.myr2
-rw-r--r--lib/thread/bld.sub9
-rw-r--r--lib/thread/condvar+freebsd.myr6
-rw-r--r--lib/thread/condvar+linux.myr6
-rw-r--r--lib/thread/future.myr2
-rw-r--r--lib/thread/mutex+freebsd.myr4
-rw-r--r--lib/thread/mutex+linux.myr4
-rw-r--r--lib/thread/mutex+plan9.myr4
-rw-r--r--lib/thread/mutex.myr4
-rw-r--r--lib/thread/test/atomic.myr2
-rw-r--r--lib/thread/test/condvar.myr2
-rw-r--r--lib/thread/test/future.myr2
-rw-r--r--lib/thread/test/mutex.myr2
-rw-r--r--mbld/deps.myr13
-rw-r--r--mbld/util.myr19
-rwxr-xr-xmk/bootstrap/bootstrap+Darwin-x86_64.sh14
-rw-r--r--muse/muse.c25
-rw-r--r--parse/gram.y2
-rw-r--r--parse/parse.h1
-rw-r--r--parse/use.c26
-rwxr-xr-xsupport/release.sh26
-rw-r--r--util/util.c10
-rw-r--r--util/util.h1
38 files changed, 444 insertions, 211 deletions
diff --git a/6/genp9.c b/6/genp9.c
index 84d845c..10092f5 100644
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -193,7 +193,6 @@ done:
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 @@ static size_t writebytes(FILE *fd, char *name, size_t off, char *p, size_t sz)
return sz;
}
-
static void genstrings(FILE *fd, Htab *strtab)
{
void **k;
@@ -245,7 +243,7 @@ static void writeasm(FILE *fd, Isel *s, Func *fn)
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 @@ static void genfunc(FILE *fd, Func *fn, Htab *globls, Htab *strtab)
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 @@ static void gentype(FILE *fd, Type *ty)
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)
diff --git a/6/main.c b/6/main.c
index b3218d8..44d569e 100644
--- a/6/main.c
+++ b/6/main.c
@@ -28,6 +28,7 @@ int extracheck = 1;
int p9asm;
char *outfile;
char **incpaths;
+char *localincpath;
size_t nincpaths;
Asmsyntax asmsyntax;
@@ -41,7 +42,7 @@ static void usage(char *prog)
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 void assemble(char *asmsrc, char *path)
}
}
+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 @@ int main(int argc, char **argv)
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 @@ int main(int argc, char **argv)
genuse(ctx.args[i]);
gen(file, buf);
assemble(buf, ctx.args[i]);
+
+ free(localincpath);
}
return 0;
diff --git a/Makefile b/Makefile
index 63aa9c9..a4161b6 100644
--- a/Makefile
+++ b/Makefile
@@ -37,3 +37,6 @@ installmyr:
uninstallmyr:
./mbldwrap.sh uninstall
+
+release:
+ ./support/release.sh 0.1
diff --git a/README.md b/README.md
index 3c6d3a7..578f96f 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,19 @@ and features you may find familiar from languages like like rust and ocaml.
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 @@ Annoucements of major changes, questions, complaints. We also give relationship
## Supported Platforms
Myrddin currently runs on a number of platforms
-- Linux
-- OSX
- FreeBSD
+- Linux
- NetBSD
-- 9front
+- OSX
+- OpenBSD
+- Plan9front
diff --git a/configure b/configure
index add1c65..417787d 100755
--- a/configure
+++ b/configure
@@ -55,6 +55,7 @@ case $OS in
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",' \
diff --git a/doc/6m.1 b/doc/6m.1
index 7ef544c..f04090c 100644
--- 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 @@ tools like 'mbld'.
.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,29 +35,39 @@ x86-64
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
.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
6m foo.myr
diff --git a/doc/lang.txt b/doc/lang.txt
index 762c4fe..6b61c19 100644
--- a/doc/lang.txt
+++ b/doc/lang.txt
@@ -53,7 +53,8 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
- 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 @@ TABLE OF CONTENTS:
- 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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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,7 +317,11 @@ TABLE OF CONTENTS:
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:
@@ -335,9 +344,11 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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,8 +443,16 @@ TABLE OF CONTENTS:
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
@@ -456,7 +476,7 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
~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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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 @@ TABLE OF CONTENTS:
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
diff --git a/doc/muse.1 b/doc/muse.1
index d417bb7..b337d6f 100644
--- a/doc/muse.1
+++ b/doc/muse.1
@@ -3,29 +3,20 @@
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
-\&.
-
-If the filename does not end with the suffix
-.I .myr
-then the suffix
-.I .o
-will simply be appended to it.
+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.
.PP
The output of muse is architecture-independent. However, the format of the
@@ -45,26 +36,25 @@ debugging information for specific intermediate states of the compilation.
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
-
-.TP
-.B -s
-Print a summary of the symbols exported from the usefile that is specified.
+should match up with the package name given to the
+.I -p
+option.
.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
diff --git a/lib/crypto/test/md5.myr b/lib/crypto/test/md5.myr
index 0548051..bc0939f 100644
--- 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("")[:], \
diff --git a/lib/crypto/test/sha1.myr b/lib/crypto/test/sha1.myr
index 22813d9..e750f41 100644
--- 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("")[:], \
diff --git a/lib/crypto/test/sha256.myr b/lib/crypto/test/sha256.myr
index e883c84..958b993 100644
--- 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("")[:], \
diff --git a/lib/crypto/test/sha512.myr b/lib/crypto/test/sha512.myr
index 0ae81e4..ddee8e8 100644
--- 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("")[:], \
diff --git a/lib/json/test/parse.myr b/lib/json/test/parse.myr
index 0045fb7..4ed65dc 100644
--- a/lib/json/test/parse.myr
+++ b/lib/json/test/parse.myr
@@ -125,7 +125,7 @@ const filetest = {
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)
diff --git a/lib/std/syswrap+plan9.myr b/lib/std/syswrap+plan9.myr
index bd3552f..ab1c025 100644
--- a/lib/std/syswrap+plan9.myr
+++ b/lib/std/syswrap+plan9.myr
@@ -77,16 +77,26 @@ pkg std =
/* 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... */
diff --git a/lib/std/test/fltbits.myr b/lib/std/test/fltbits.myr
index 0571b10..4e64137 100644
--- 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")
}
diff --git a/lib/sys/sys+openbsd-x64.myr b/lib/sys/sys+openbsd-x64.myr
index 466988b..0f3cf02 100644
--- 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 */
diff --git a/lib/thread/bld.sub b/lib/thread/bld.sub
index 3cc710a..8f892f1 100644
--- a/lib/thread/bld.sub
+++ b/lib/thread/bld.sub
@@ -18,10 +18,10 @@ lib thread =
# 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
@@ -39,7 +39,6 @@ lib thread =
spawn+openbsd.myr
exit+openbsd-x64.s
-
atomic-impl+x64.s
atomic.myr
diff --git a/lib/thread/condvar+freebsd.myr b/lib/thread/condvar+freebsd.myr
index 24e5a32..65267a4 100644
--- 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
diff --git a/lib/thread/condvar+linux.myr b/lib/thread/condvar+linux.myr
index 9e288d7..cd4ab8c 100644
--- 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
diff --git a/lib/thread/future.myr b/lib/thread/future.myr
index da6252b..5637e6d 100644
--- 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
diff --git a/lib/thread/mutex+freebsd.myr b/lib/thread/mutex+freebsd.myr
index d66fd53..fc1f8c2 100644
--- 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
diff --git a/lib/thread/mutex+linux.myr b/lib/thread/mutex+linux.myr
index 37bec62..22b9904 100644
--- 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
diff --git a/lib/thread/mutex+plan9.myr b/lib/thread/mutex+plan9.myr
index 7c87218..e91cd90 100644
--- a/lib/thread/mutex+plan9.myr
+++ b/lib/thread/mutex+plan9.myr
@@ -2,8 +2,8 @@ use std
use sys
-use "atomic.use"
-use "common.use"
+use "atomic"
+use "common"
pkg thread =
type mutex = struct
diff --git a/lib/thread/mutex.myr b/lib/thread/mutex.myr
index 6dc4a44..5b90574 100644
--- a/lib/thread/mutex.myr
+++ b/lib/thread/mutex.myr
@@ -2,8 +2,8 @@ use std
use sys
-use "atomic.use"
-use "common.use"
+use "atomic"
+use "common"
pkg thread =
type mutex = struct
diff --git a/lib/thread/test/atomic.myr b/lib/thread/test/atomic.myr
index c005677..3dd3284 100644
--- 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
diff --git a/lib/thread/test/condvar.myr b/lib/thread/test/condvar.myr
index e8670b1..0f1de58 100644
--- 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
diff --git a/lib/thread/test/future.myr b/lib/thread/test/future.myr
index 63969a4..e69e1af 100644
--- a/lib/thread/test/future.myr
+++ b/lib/thread/test/future.myr
@@ -2,7 +2,7 @@ use std
use sys
use thread
-use "test/util.use"
+use "util"
var fut
var nready : int32
diff --git a/lib/thread/test/mutex.myr b/lib/thread/test/mutex.myr
index e29ae85..b366637 100644
--- 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
diff --git a/mbld/deps.myr b/mbld/deps.myr
index 0b66b5b..59a4e75 100644
--- a/mbld/deps.myr
+++ b/mbld/deps.myr
@@ -148,7 +148,7 @@ const srcdeps = {b, ds, g, path, obj, usefile
;;
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 @@ const getcflags = {ln, cflags, libs
-> (cflags, libs)
}
-const getdeps = {b, ds, path
+const getdeps = {b, ds, path, dir
var deps, lnum
var f
@@ -266,7 +266,7 @@ const getdeps = {b, ds, path
| `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 opensrc = {b, path
;;
}
-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 @@ const depname = {deps, ln, lnum
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:
diff --git a/mbld/util.myr b/mbld/util.myr
index 7054ac5..dc03bdc 100644
--- a/mbld/util.myr
+++ b/mbld/util.myr
@@ -59,22 +59,27 @@ const printcmd = {lst
}
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 */
;;
diff --git a/mk/bootstrap/bootstrap+Darwin-x86_64.sh b/mk/bootstrap/bootstrap+Darwin-x86_64.sh
index 72b014a..37170bd 100755
--- a/mk/bootstrap/bootstrap+Darwin-x86_64.sh
+++ b/mk/bootstrap/bootstrap+Darwin-x86_64.sh
@@ -7,10 +7,11 @@ echo as -g -o util.o util+posixy-x64.s && as -g -o util.o util+posixy-x64.s
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 . sljoin.myr && $pwd/6/6m -I ../sys -I . sljoin.m
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 . iterutil.myr && $pwd/6/6m -I ../sys -I . iterut
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 . getcwd.myr && $pwd/6/6m -I ../sys -I . getcwd.m
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 &&\
diff --git a/muse/muse.c b/muse/muse.c
index ccd8c58..3aac36d 100644
--- a/muse/muse.c
+++ b/muse/muse.c
@@ -25,13 +25,13 @@ char **incpaths;
size_t nincpaths;
char **extralibs;
size_t nextralibs;
+char *localincpath;
static void usage(char *prog)
{
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 @@ int main(int argc, char **argv)
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 @@ int main(int argc, char **argv)
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 @@ int main(int argc, char **argv)
}
}
- 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 @@ int main(int argc, char **argv)
/* 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;
}
diff --git a/parse/gram.y b/parse/gram.y
index bc3e114..540a4fe 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -287,7 +287,7 @@ attrs : /* empty */ {$$.nstr = 0; $$.str = NULL;}
;
decllist: declbody {
- $$.nl = NULL; $$.nn = 0;
+ $$.loc = $1->loc; $$.nl = NULL; $$.nn = 0;
lappend(&$$.nl, &$$.nn, $1);
}
| declbody Tcomma decllist {
diff --git a/parse/parse.h b/parse/parse.h
index caa5181..83f3ae6 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -559,5 +559,6 @@ extern int asmonly;
extern char *outfile;
extern char **incpaths;
extern size_t nincpaths;
+extern char *localincpath;
void yyerror(const char *s);
diff --git a/parse/use.c b/parse/use.c
index 70cd299..28132bd 100644
--- a/parse/use.c
+++ b/parse/use.c
@@ -1031,18 +1031,18 @@ void readuse(Node *use, Stab *st, Vis vis)
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 @@ void readuse(Node *use, Stab *st, Vis vis)
}
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))
diff --git a/support/release.sh b/support/release.sh
new file mode 100755
index 0000000..b2740d5
--- /dev/null
+++ b/support/release.sh
@@ -0,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.* .
+
diff --git a/util/util.c b/util/util.c
index dccc90b..904ef26 100644
--- a/util/util.c
+++ b/util/util.c
@@ -24,6 +24,16 @@ char *strdupn(char *s, size_t len)
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;
diff --git a/util/util.h b/util/util.h
index 60a344b..49f10d6 100644
--- a/util/util.h
+++ b/util/util.h
@@ -121,6 +121,7 @@ void *zrealloc(void *p, size_t oldsz, size_t size);
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, ...);