Fixing a few spelling errors.

Fixing a few spelling errors.

I did not do a complete review, just fixing the existing spelling
errors.

Who the heck wrote this thing anyways?!!?!

git-svn-id: 88467cb1fb04b8a755be7e1ee1026be4190196ef@19853 3a8e244f-b0f2-452b-bcba-4c88e055c3ca

//
// Sync and Single Variables Primer
//
// This primer illustrates Chapel's sync and single variables.
//
config const n = 7;

// Sync and single are type qualifiers that can be applied to all
// Chapel primitive types except strings, complex, and record.
//

// Sync and single variables have an associated state that is either
// 'full' or 'empty'.  Single variables are sync variables that can
// only be written once.  If a sync or single variable is declared
// with an initializing expression, its state is set to full and its
// value is that of the expression.  Without an initializing
// expression, a sync or single variable's state is set to empty and
// its value is the default value for the base type.
//
var sy$: sync int=1;  // state = full, value = 1
var si$: single bool; // state = empty, value = false

// By convention, sync and single variable names end in a $ to
// add a visual cue indicating that reads and writes are possibly
// expensive operations and can potentially block the task.
//

// For both sync and single variables, the state must be empty before
// the value can be written.  When the write has completed, the state
// is set to full.
//
si$ = true; // state = full, value = true

// For both sync and single variables, the state must be full before the
// value can be read.  When the read has completed, the state of a
// sync variable is set to empty, and the state of a single variable
// remains full.
//
var sy = sy$; // sy$: state = empty
var si = si$; // si$: state = full

// If a sync or single variable is not in the correct state for reading
// (full) or writing (empty), the current task blocks.
//
// The following creates a new task via a begin statement and declares
// a variable sy that is initialized to sy$.  The initialization statement
// will block until sy$ is full.  The last statement in the begin
// block sets the done$ to full.
//
var done$: sync bool;
writeln("Launching new task");
begin {
  var sy = sy$; // This statement will block until sy$ is full
  writeln("New task unblocked, sy=", sy);
  done$ = true;
}

// Recall that execution proceeds immediately following the begin
// statement after task creation.
//
writeln("After launching new task");
// When sy$ is written, its state will be set to full and the blocked
// task above will continue.
//
sy$ = n;
// This next statement blocks until last statement in the above begin
// completes.
//
done$;

//
// Example: simple split-phase barrier for tasks
//
var count$: sync int = n;  // counter which also serves as a lock
var release$: single bool; // barrier release

coforall t in 1..n {
  var myc = count$;   // read the count, grab the lock (state = empty)
  if myc!=1 {         // still waiting for others
    write(".");
    count$ = myc-1;   // update the count, release the lock (state = full)
                      // we could do some work while waiting
    release$;         // wait for everyone
  } else {            // last one here
    release$ = true;  // release everyone first (state = full)
    writeln("done");
  }
}

//
// There are a number of methods defined for sync and single variables.
//

// The reset() method, defined for sync variables, sets the value of
// the variable to the default value for the type and the state to
// empty.
//
sy$.reset();  // value = 0, state = full

// The isFull method returns true if the sync or single variable is
// in the full state, false otherwise.
//
writeln(sy$.isFull);
writeln(si$.isFull);

// The writeEF() method, defined for sync and single variables,
// blocks until the state is empty and then assigns the value argument
// to the variable and then sets the state to full.  Assignment of
// sync and single variables are performed using writeEF().
//
sy$.writeEF(2*n); // equivalent to: sy$ = 2*n;

// The readFE() method, defined for sync variables, blocks until the
// state is full and then reads the value of the variable, sets the
// state to full, and then returns the value.  Normal reads of sync
// variables are performed using readFE().
//
var sy2 = sy$.readFE(); // equivalent to: var sy2 = sy$;
writeln(sy2);

// The readFF() method, defined for sync and single variables, blocks
// until the state is full and then reads the value of the variable
// and returns the value.  The state remains full.  Normal reads of
// single variables are performed using readFF().
//
var si2 = si$.readFF();
writeln(si2);

// The writeXF() method, defined for sync variables, assigns the
// value argument to the variable and then sets the state to full.
// This method does not block.
//
sy$.writeXF(3*n);

// The readXX() method, defined for sync and single variables, returns
// the value of the variable regardless of the state.  This method
// does not block and the state is unchanged.
//
var sy3 = sy$.readXX();
var si3 = si$.readXX();
writeln(sy3);
writeln(si3);

// The writeFF() method, defined for sync variables, blocks until the
// state is full and then and then assigns the value argument to the
// variable.  The state is unchanged.
//
sy$.writeFF(4*n);

sy$.reset();
// Sync and single arguments are passed by reference.  As a result,
// the state of the variable does not change.
//
writeln(sy$.isFull);
f_withSyncIntFormal(sy$);
writeln(si$.isFull);
f_withSingleBoolFormal(si$);

sy$ = 4*n;
// When a sync or single variable is passed as an argument to a
// function that expects the base type of the variable, the value is
// read before being passed to the function.  Therefore, the task will
// block until the state of the variable is full.
//
f_withIntFormal(sy$);
f_withBoolFormal(si$);

sy$ = 5*n;
// Similarly, when a sync or single variable is passed as an argument
// to a generic function such as writeln(), the value is read before
// being passed to the function.  The generic formal argument is set
// to be the base type of the actual.
//
writeln(sy$);
writeln(si$);

proc f_withSyncIntFormal(x: sync int) {
  writeln(x.isFull);
}

proc f_withSingleBoolFormal(x: single bool) {
  writeln(x.isFull);
}

proc f_withIntFormal(x: int) {
  writeln(x);
}

proc f_withBoolFormal(x: bool) {
  writeln(x);
}

//
// Sync and Single Variables Primer
//
// This primer illustrations Chapel's sync and single variables.
//
config const n = 7;

// Sync and single are type qualifiers that can be applied to all
// Chapel primitive types except strings, complex, and record.
//

// Sync and single variables have an associated state that is either
// 'full' or 'empty'.  Single variables are sync variables that can
// only be written once.  If a sync or single variable is declared
// with an initializing expression, its state is set to full and its
// value is that of the expression.  Without an initializing
// expression, a sync or single variable's state is set to empty and
// its value is the default value for the base type.
//
var sy$: sync int=1;  // state = full, value = 1
var si$: single bool; // state = empty, value = false

// By convention, sync and single variable names end in a $ to
// add a visual cue indicating that reads and writes are possibly
// expensive operations and can potentially block the task.
//

// For both sync and single variables, the state must be empty before
// the value can be written.  When the write has completed, the state
// is set to full.
//
si$ = true; // state = full, value = true

// For both sync and single variables, the state must be full before the
// value can be read.  When the read has completed, the state of a
// sync variable is set to empty, and the state of a single variable
// remains full.
//
var sy = sy$; // sy$: state = empty
var si = si$; // si$: state = full

// If a sync or single variable is not in the correct state for reading
// (full) or writing (empty), the current task blocks.
//
// The following creates a new task via a begin statement and declares
// a variable sy that is initialized to sy$.  The initialization statement
// will block until sy$ is full.  The last statement in the begin
// block sets the done$ to full.
//
var done$: sync bool;
writeln("Launching new task");
begin {
  var sy = sy$; // This statement will block until sy$ is full
  writeln("New task unblocked, sy=", sy);
  done$ = true;
}

// Recall that execution proceeds immediately following the begin
// statement after task creation.
//
writeln("After launching new task");
// When sy$ is written, its state will be set to full and the blocked
// task above will continue.
//
sy$ = n;
// This next statement blocks until last statement in the above begin
// completes.
//
done$;

//
// Example: simple split-phase barrier for tasks
//
var count$: sync int = n;  // counter which also serves as a lock
var release$: single bool; // barrier release

coforall t in 1..n {
  var myc = count$;   // read the count, grab the lock (state = empty)
  if myc!=1 {         // still waiting for others
    write(".");
    count$ = myc-1;   // update the count, release the lock (state = full)
                      // we could do some work while waiting
    release$;         // wait for everyone
  } else {            // last one here
    release$ = true;  // release everyone first (state = full)
    writeln("done");
  }
}

//
// There are a number of methods defined for sync and single variables.
//

// The reset() method, defined for sync variables, sets the value of
// the variable to the default value for the type and the state to
// empty.
//
sy$.reset();  // value = 0, state = full

// The isFull method returns true if the sync or single variable is
// in the full state, false otherwise.
//
writeln(sy$.isFull);
writeln(si$.isFull);

// The writeEF() method, defined for sync and single variables,
// blocks until the state is empty and then assigns the value argument
// to the variable and then sets the state to full.  Assignment of
// sync and single variables are performed using writeEF().
//
sy$.writeEF(2*n); // equivalent to: sy$ = 2*n;

// The readFE() method, defined for sync variables, blocks until the
// state is full and then reads the value of the variable, sets the
// state to full, and then returns the value.  Normal reads of sync
// variables are performed using readFE().
//
var sy2 = sy$.readFE(); // equivalent to: var sy2 = sy$;
writeln(sy2);

// The readFF() method, defined for sync and single variables, blocks
// until the state is full and then reads the value of the variable
// and returns the value.  The state remains full.  Normal reads of
// single variables are performed using readFF().
//
var si2 = si$.readFF();
writeln(si2);

// The writeXF() method, definded for sync variables, assigns the
// value argument to the variable and then sets the state to full.
// This method does not block.
//
sy$.writeXF(3*n);

// The readXX() method, defined for sync and single variables, returns
// the value of the variable regardless of the state.  This method
// does not block and the state is unchanged.
//
var sy3 = sy$.readXX();
var si3 = si$.readXX();
writeln(sy3);
writeln(si3);

// The writeFF() method, defined for sync variables, blocks until the
// state is full and then and then assigns the value argument to the
// variable.  The state is unchanged.
//
sy$.writeFF(4*n);

sy$.reset();
// Sync and single arguments are passed by reference.  As a result,
// the state of the variable does not change.
//
writeln(sy$.isFull);
f_withSyncIntFormal(sy$);
writeln(si$.isFull);
f_withSingleBoolFormal(si$);

sy$ = 4*n;
// When a sync or single variable is passed as an argument to a
// function that expects the base type of the variable, the value is
// read before being passed to the function.  Therefore, the task will
// block until the state of the variable is full.
//
f_withIntFormal(sy$);
f_withBoolFormal(si$);

sy$ = 5*n;
// Similarly, when a sync or single variable is passed as an argument
// to a generic function such as writeln(), the value is read before
// being passed to the function.  The generic formal argument is set
// to be the base type of the actual.
//
writeln(sy$);
writeln(si$);

proc f_withSyncIntFormal(x: sync int) {
  writeln(x.isFull);
}

proc f_withSingleBoolFormal(x: single bool) {
  writeln(x.isFull);
}

proc f_withIntFormal(x: int) {
  writeln(x);
}

proc f_withBoolFormal(x: bool) {
  writeln(x);
}


Temporary fix to serialize write/writeln's so that we get fewer cases of
nondeterministic output. Basically, use a sync bool as a lock to
writes to stdout.  A slightly more elegant solution requires a small fix
to sync vars.

git-svn-id: 88467cb1fb04b8a755be7e1ee1026be4190196ef@6794 3a8e244f-b0f2-452b-bcba-4c88e055c3ca

//
// Functions on _file primitive type, the C file pointer type
//

pragma "no codegen" var chpl_input_filename: string;
pragma "no codegen" var chpl_input_lineno: int;

pragma "inline" fun _get_errno() return __primitive("get_errno");
pragma "inline" fun _get_eof() return __primitive("get_eof");
pragma "inline" fun _get_stdin() return __primitive("get_stdin");
pragma "inline" fun _get_stdout() return __primitive("get_stdout");
pragma "inline" fun _get_stderr() return __primitive("get_stderr");
pragma "inline" fun _get_nullfile() return __primitive("get_nullfile");

pragma "inline" fun _copy(x: _file) return x;
pragma "inline" fun =(a: _file, b: _file) return b;
pragma "inline" fun ==(a: _file, b: _file) return __primitive("==", a, b);
pragma "inline" fun !=(a: _file, b: _file) return __primitive("!=", a, b);

pragma "inline" fun _fopen(filename: string, mode: string)
  return __primitive("fopen", filename, mode);

pragma "inline" fun _fclose(fp: _file)
  return __primitive("fclose", fp);

pragma "inline" fun fprintf(fp: _file, fmt: string, val)
  return __primitive("fprintf", fp, fmt, val);

pragma "inline" fun fscanf(fp: _file, fmt: string, inout val)
  return __primitive("fscanf", fp, fmt, val);

pragma "inline" fun _string_fscanf(fp: _file)
  return __primitive("string_fscanf", fp);

pragma "inline" fun _readLitChar(fp: _file, val: string, ignoreWhiteSpace: bool)
  return __primitive("readLit", fp, val, ignoreWhiteSpace);

pragma "rename _chpl_fflush"
fun fflush(f: file) {
  fflush(f.fp);
}

pragma "rename _chpl_fflush_nil"
fun fflush(f: _nilType) {
  halt("***Error: called fflush on nil***");
}

pragma "rename _chpl_assert_no_args"
fun assert(test: bool) {
  if (!test) {
    _writeAssertFailed();
    if (!chpl_input_lineno) {
      fwriteln(stderr);
    }
    exit(0);
  }
}

pragma "rename _chpl_assert"
fun assert(test: bool, args ...?numArgs) {
  if (!test) {
    _writeAssertFailed();
    if (!chpl_input_lineno) {
      fwrite(stderr, ": ");
    }
    for param i in 1..numArgs {
      fwrite(stderr, args(i));
    }
    fwriteln(stderr);
    exit(0);
  }
}

fun _writeAssertFailed() {
  fflush(stdout);
  fwrite(stderr, "Assertion failed");
  if (chpl_input_lineno) {
    fwriteln(stderr, ": ", chpl_input_filename, ":", chpl_input_lineno);
  }
}

pragma "rename _chpl_halt_no_args"
fun halt() {
  _writeHaltReached();
  if(!chpl_input_lineno) {
    fwriteln(stderr);
  }
  exit(0);
}

pragma "rename _chpl_halt"
fun halt(args ...?numArgs) {
  _writeHaltReached();
  if (!chpl_input_lineno) {
    fwrite(stderr, ": ");
  }
  for param i in 1..numArgs {
    fwrite(stderr, args(i));
  }
  fwriteln(stderr);
  exit(0);
}

fun _writeHaltReached() {
  fflush(stdout);
  fwrite(stderr, "Halt reached");
  if (chpl_input_lineno) {
    fwriteln(stderr, ": ", chpl_input_filename, ":", chpl_input_lineno);
  }
}

class file {
  var filename : string = "";
  var mode : string = "r";
  var path : string = ".";
  var fp : _file;

  fun open {
    if (this == stdin || this == stdout || this == stderr) {
      halt("***Error: It is not necessary to open \"", filename, "\"***");
    }

    var fullFilename = path + "/" + filename;
    fp = _fopen(fullFilename, mode);

    if (fp == _get_nullfile()) {
      halt("***Error: Unable to open \"", fullFilename, "\": ",
           _get_errno(), "***");
    }
  }

  fun isOpen: bool {
    var openStatus: bool = false;
    if (fp != _get_nullfile()) {
      openStatus = true;
    }
    return openStatus;
  }

  fun close {
    if (this == stdin || this == stdout || this == stderr) {
      halt("***Error: You may not close \"", filename, "\"***");
    }
    if (fp == _get_nullfile()) {
      var fullFilename = path + "/" + filename;
      halt("***Error: Trying to close \"", fullFilename,
           "\" which isn't open***");
    }
    var returnVal: int = _fclose(fp);
    if (returnVal < 0) {
      var fullFilename = path + "/" + filename;
      halt("***Error: The close of \"", fullFilename, "\" failed: ",
           _get_errno(), "***");
    }
    fp = _get_nullfile();
  }
}

const stdin  : file = file("stdin", "r", "/dev", _get_stdin());
const stdout : file = file("stdout", "w", "/dev", _get_stdout());
const stderr : file = file("stderr", "w", "/dev", _get_stderr());

fun fopenError(f: file, isRead: bool) {
  var fullFilename:string = f.path + "/" + f.filename;
  if (isRead) {
    halt("***Error: You must open \"", fullFilename,
         "\" before trying to read from it***");
  } else {
    halt("***Error: You must open \"", fullFilename,
         "\" before trying to write to it***");
  }
}

fun fprintfError() {
  halt("***Error: Write failed: ", _get_errno(), "***");
}

fun fscanfError() {
  halt("***Error: Read failed: ", _get_errno(), "***");
}

pragma "rename _chpl_fread_int"
fun fread(f: file = stdin, inout val: int) {
  if (f.isOpen) {
    var returnVal: int = fscanf(f.fp, "%lld", val);
    if (returnVal == _get_eof()) {
      halt("***Error: Read failed: EOF***");
    }
    if (returnVal < 0) {
      fscanfError();
    } else if (returnVal == 0) {
      halt("***Error: No int was read***");
    }
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_int"
fun fwrite(f: file, val: int) {
  if (f.isOpen) {
    var returnVal: int = fprintf(f.fp, "%lld", val);
    if (returnVal < 0) {
      fprintfError();
    } else if (returnVal == 0) {
      halt("***Error: No int was written***");
    }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_uint"
fun fread(f: file = stdin, inout val: uint) {
  if (f.isOpen) {
    var returnVal: int = fscanf(f.fp, "%llu", val);
    if (returnVal == _get_eof()) {
      halt("***Error: Read failed: EOF***");
    }
    if (returnVal < 0) {
      fscanfError();
    } else if (returnVal == 0) {
      halt("***Error: No int was read***");
    }
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_uint"
fun fwrite(f: file, val: uint) {
  if (f.isOpen) {
    var returnVal: int = fprintf(f.fp, "%llu", val);
    if (returnVal < 0) {
      fprintfError();
    } else if (returnVal == 0) {
      halt("***Error: No int was written***");
    }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_float"
fun fread(f: file = stdin, inout val: float) {
  if (f.isOpen) {
    var returnVal: int = fscanf(f.fp, "%lg", val);
    if (returnVal == _get_eof()) {
      halt("***Error: Read failed: EOF***");
    }
    if (returnVal < 0) {
      fscanfError();
    } else if (returnVal == 0) {
      halt("***Error: No float was read***");
    }
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_float"
fun fwrite(f: file, val: float) {
  if (f.isOpen) {
    var returnVal : int;
    var str : string = val:"%g";
    if (_string_contains(str, ".") || _string_contains(str, "e")) {
      returnVal = fprintf(f.fp, "%s", str);
    } else {
      returnVal = fprintf(f.fp, "%s.0", str);
    }
    if returnVal < 0 then
      fprintfError();
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_complex"
fun fread(f: file = stdin, inout val: complex) {
  var realPart: float;
  var imagPart: float;
  var imagI: string;
  var matchingCharWasRead: int;
  var isNeg: bool;

  fread(f, realPart);
  matchingCharWasRead = _readLitChar(f.fp, "+", true);
  if (matchingCharWasRead != 1) {
    matchingCharWasRead = _readLitChar(f.fp, "-", true);
    if (matchingCharWasRead != 1) {
      halt("***Error: Incorrect format for complex numbers***");
    }
    isNeg = true;
  }

  fread(f, imagPart);
  matchingCharWasRead = _readLitChar(f.fp, "i", false);
  if (matchingCharWasRead != 1) {
    halt("***Error: Incorrect format for complex numbers***");
  }

  val.real = realPart;
  if (isNeg) {
    val.imag = -imagPart;
  } else {
    val.imag = imagPart;
  }
}

pragma "rename _chpl_fwrite_complex"
fun fwrite(f: file, val: complex) {
  if (f.isOpen) {
     fwrite(f, val.real);
     if (val.imag >= 0) {
       fwrite(f, " + ", val.imag, "i");
     } else {
       fwrite(f, " - ", -val.imag, "i");
     }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_string"
fun fread(f: file = stdin, inout val: string) {
  if (f.isOpen) {
    val = _string_fscanf(f.fp);
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_string"
fun fwrite(f: file, val: string) {
  if (f.isOpen) {
    var returnVal: int = fprintf(f.fp, "%s", val);
    if (returnVal < 0) {
      fprintfError();
    }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_bool"
fun fread(f: file = stdin, inout val: bool) {
  if (f.isOpen) {
    var valString : string = _string_fscanf(f.fp);
    if (valString == "true") {
      val = true;
    } else if (valString == "false") {
      val = false;
    } else {
      halt("***Error: Not of bool type***");
    }
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_bool"
fun fwrite(f: file, val: bool) {
  if (f.isOpen) {
    var returnVal: int;
    if (val == true) {
      returnVal = fprintf(f.fp, "%s", "true");
    } else {
      returnVal = fprintf(f.fp, "%s", "false");
    }
    if (returnVal < 0) {
      fprintfError();
    }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fwrite_syncvar"
fun fwrite(f: file, sv: _syncvar) {
  fwrite(f, sv.value);
}

pragma "rename _chpl_fwrite_nil"
fun fwrite(f: file, x : _nilType) : void {
  if (f.isOpen) {
    var returnVal: int = fprintf(f.fp, "%s", "nil");
    if (returnVal < 0) {
      fprintfError();
    }
  } else {
    fopenError(f, isRead = false);
  }
}

fun fwrite(f: file, args ...?numArgs) {
  for param i in 1..numArgs {
    fwrite(f, args(i));
  }
}

fun fwriteln(f: file, args ...?numArgs) {
  fwrite(f, (...args));
  fwriteln(f);
}

fun fwriteln(f: file) {
  fwrite(f, "\n");
}

var _stdout_lock: sync bool;

fun write(args ...?numArgs) {
  var bogus: bool;
  _stdout_lock = true;
  fwrite(stdout, (...args));
  bogus = _stdout_lock;
}

fun writeln(args ...?numArgs) {
  var bogus: bool;
  _stdout_lock = true;
  fwriteln(stdout, (...args));
  bogus = _stdout_lock;
}

fun writeln() {
  var bogus: bool;
  _stdout_lock = true;
  fwriteln(stdout);
  bogus = _stdout_lock;
}

//
// Functions on _file primitive type, the C file pointer type
//

pragma "no codegen" var chpl_input_filename: string;
pragma "no codegen" var chpl_input_lineno: int;

pragma "inline" fun _get_errno() return __primitive("get_errno");
pragma "inline" fun _get_eof() return __primitive("get_eof");
pragma "inline" fun _get_stdin() return __primitive("get_stdin");
pragma "inline" fun _get_stdout() return __primitive("get_stdout");
pragma "inline" fun _get_stderr() return __primitive("get_stderr");
pragma "inline" fun _get_nullfile() return __primitive("get_nullfile");

pragma "inline" fun _copy(x: _file) return x;
pragma "inline" fun =(a: _file, b: _file) return b;
pragma "inline" fun ==(a: _file, b: _file) return __primitive("==", a, b);
pragma "inline" fun !=(a: _file, b: _file) return __primitive("!=", a, b);

pragma "inline" fun _fopen(filename: string, mode: string)
  return __primitive("fopen", filename, mode);

pragma "inline" fun _fclose(fp: _file)
  return __primitive("fclose", fp);

pragma "inline" fun fprintf(fp: _file, fmt: string, val)
  return __primitive("fprintf", fp, fmt, val);

pragma "inline" fun fscanf(fp: _file, fmt: string, inout val)
  return __primitive("fscanf", fp, fmt, val);

pragma "inline" fun _string_fscanf(fp: _file)
  return __primitive("string_fscanf", fp);

pragma "inline" fun _readLitChar(fp: _file, val: string, ignoreWhiteSpace: bool)
  return __primitive("readLit", fp, val, ignoreWhiteSpace);

pragma "rename _chpl_fflush"
fun fflush(f: file) {
  fflush(f.fp);
}

pragma "rename _chpl_fflush_nil"
fun fflush(f: _nilType) {
  halt("***Error: called fflush on nil***");
}

pragma "rename _chpl_assert_no_args"
fun assert(test: bool) {
  if (!test) {
    _writeAssertFailed();
    if (!chpl_input_lineno) {
      fwriteln(stderr);
    }
    exit(0);
  }
}

pragma "rename _chpl_assert"
fun assert(test: bool, args ...?numArgs) {
  if (!test) {
    _writeAssertFailed();
    if (!chpl_input_lineno) {
      fwrite(stderr, ": ");
    }
    for param i in 1..numArgs {
      fwrite(stderr, args(i));
    }
    fwriteln(stderr);
    exit(0);
  }
}

fun _writeAssertFailed() {
  fflush(stdout);
  fwrite(stderr, "Assertion failed");
  if (chpl_input_lineno) {
    fwriteln(stderr, ": ", chpl_input_filename, ":", chpl_input_lineno);
  }
}

pragma "rename _chpl_halt_no_args"
fun halt() {
  _writeHaltReached();
  if(!chpl_input_lineno) {
    fwriteln(stderr);
  }
  exit(0);
}

pragma "rename _chpl_halt"
fun halt(args ...?numArgs) {
  _writeHaltReached();
  if (!chpl_input_lineno) {
    fwrite(stderr, ": ");
  }
  for param i in 1..numArgs {
    fwrite(stderr, args(i));
  }
  fwriteln(stderr);
  exit(0);
}

fun _writeHaltReached() {
  fflush(stdout);
  fwrite(stderr, "Halt reached");
  if (chpl_input_lineno) {
    fwriteln(stderr, ": ", chpl_input_filename, ":", chpl_input_lineno);
  }
}

class file {
  var filename : string = "";
  var mode : string = "r";
  var path : string = ".";
  var fp : _file;

  fun open {
    if (this == stdin || this == stdout || this == stderr) {
      halt("***Error: It is not necessary to open \"", filename, "\"***");
    }

    var fullFilename = path + "/" + filename;
    fp = _fopen(fullFilename, mode);

    if (fp == _get_nullfile()) {
      halt("***Error: Unable to open \"", fullFilename, "\": ",
           _get_errno(), "***");
    }
  }

  fun isOpen: bool {
    var openStatus: bool = false;
    if (fp != _get_nullfile()) {
      openStatus = true;
    }
    return openStatus;
  }

  fun close {
    if (this == stdin || this == stdout || this == stderr) {
      halt("***Error: You may not close \"", filename, "\"***");
    }
    if (fp == _get_nullfile()) {
      var fullFilename = path + "/" + filename;
      halt("***Error: Trying to close \"", fullFilename,
           "\" which isn't open***");
    }
    var returnVal: int = _fclose(fp);
    if (returnVal < 0) {
      var fullFilename = path + "/" + filename;
      halt("***Error: The close of \"", fullFilename, "\" failed: ",
           _get_errno(), "***");
    }
    fp = _get_nullfile();
  }
}

const stdin  : file = file("stdin", "r", "/dev", _get_stdin());
const stdout : file = file("stdout", "w", "/dev", _get_stdout());
const stderr : file = file("stderr", "w", "/dev", _get_stderr());

fun fopenError(f: file, isRead: bool) {
  var fullFilename:string = f.path + "/" + f.filename;
  if (isRead) {
    halt("***Error: You must open \"", fullFilename,
         "\" before trying to read from it***");
  } else {
    halt("***Error: You must open \"", fullFilename,
         "\" before trying to write to it***");
  }
}

fun fprintfError() {
  halt("***Error: Write failed: ", _get_errno(), "***");
}

fun fscanfError() {
  halt("***Error: Read failed: ", _get_errno(), "***");
}

pragma "rename _chpl_fread_int"
fun fread(f: file = stdin, inout val: int) {
  if (f.isOpen) {
    var returnVal: int = fscanf(f.fp, "%lld", val);
    if (returnVal == _get_eof()) {
      halt("***Error: Read failed: EOF***");
    }
    if (returnVal < 0) {
      fscanfError();
    } else if (returnVal == 0) {
      halt("***Error: No int was read***");
    }
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_int"
fun fwrite(f: file, val: int) {
  if (f.isOpen) {
    var returnVal: int = fprintf(f.fp, "%lld", val);
    if (returnVal < 0) {
      fprintfError();
    } else if (returnVal == 0) {
      halt("***Error: No int was written***");
    }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_uint"
fun fread(f: file = stdin, inout val: uint) {
  if (f.isOpen) {
    var returnVal: int = fscanf(f.fp, "%llu", val);
    if (returnVal == _get_eof()) {
      halt("***Error: Read failed: EOF***");
    }
    if (returnVal < 0) {
      fscanfError();
    } else if (returnVal == 0) {
      halt("***Error: No int was read***");
    }
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_uint"
fun fwrite(f: file, val: uint) {
  if (f.isOpen) {
    var returnVal: int = fprintf(f.fp, "%llu", val);
    if (returnVal < 0) {
      fprintfError();
    } else if (returnVal == 0) {
      halt("***Error: No int was written***");
    }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_float"
fun fread(f: file = stdin, inout val: float) {
  if (f.isOpen) {
    var returnVal: int = fscanf(f.fp, "%lg", val);
    if (returnVal == _get_eof()) {
      halt("***Error: Read failed: EOF***");
    }
    if (returnVal < 0) {
      fscanfError();
    } else if (returnVal == 0) {
      halt("***Error: No float was read***");
    }
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_float"
fun fwrite(f: file, val: float) {
  if (f.isOpen) {
    var returnVal : int;
    var str : string = val:"%g";
    if (_string_contains(str, ".") || _string_contains(str, "e")) {
      returnVal = fprintf(f.fp, "%s", str);
    } else {
      returnVal = fprintf(f.fp, "%s.0", str);
    }
    if returnVal < 0 then
      fprintfError();
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_complex"
fun fread(f: file = stdin, inout val: complex) {
  var realPart: float;
  var imagPart: float;
  var imagI: string;
  var matchingCharWasRead: int;
  var isNeg: bool;

  fread(f, realPart);
  matchingCharWasRead = _readLitChar(f.fp, "+", true);
  if (matchingCharWasRead != 1) {
    matchingCharWasRead = _readLitChar(f.fp, "-", true);
    if (matchingCharWasRead != 1) {
      halt("***Error: Incorrect format for complex numbers***");
    }
    isNeg = true;
  }

  fread(f, imagPart);
  matchingCharWasRead = _readLitChar(f.fp, "i", false);
  if (matchingCharWasRead != 1) {
    halt("***Error: Incorrect format for complex numbers***");
  }

  val.real = realPart;
  if (isNeg) {
    val.imag = -imagPart;
  } else {
    val.imag = imagPart;
  }
}

pragma "rename _chpl_fwrite_complex"
fun fwrite(f: file, val: complex) {
  if (f.isOpen) {
     fwrite(f, val.real);
     if (val.imag >= 0) {
       fwrite(f, " + ", val.imag, "i");
     } else {
       fwrite(f, " - ", -val.imag, "i");
     }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_string"
fun fread(f: file = stdin, inout val: string) {
  if (f.isOpen) {
    val = _string_fscanf(f.fp);
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_string"
fun fwrite(f: file, val: string) {
  if (f.isOpen) {
    var returnVal: int = fprintf(f.fp, "%s", val);
    if (returnVal < 0) {
      fprintfError();
    }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fread_bool"
fun fread(f: file = stdin, inout val: bool) {
  if (f.isOpen) {
    var valString : string = _string_fscanf(f.fp);
    if (valString == "true") {
      val = true;
    } else if (valString == "false") {
      val = false;
    } else {
      halt("***Error: Not of bool type***");
    }
  } else {
    fopenError(f, isRead = true);
  }
}

pragma "rename _chpl_fwrite_bool"
fun fwrite(f: file, val: bool) {
  if (f.isOpen) {
    var returnVal: int;
    if (val == true) {
      returnVal = fprintf(f.fp, "%s", "true");
    } else {
      returnVal = fprintf(f.fp, "%s", "false");
    }
    if (returnVal < 0) {
      fprintfError();
    }
  } else {
    fopenError(f, isRead = false);
  }
}

pragma "rename _chpl_fwrite_syncvar"
fun fwrite(f: file, sv: _syncvar) {
  fwrite(f, sv.value);
}

pragma "rename _chpl_fwrite_nil"
fun fwrite(f: file, x : _nilType) : void {
  if (f.isOpen) {
    var returnVal: int = fprintf(f.fp, "%s", "nil");
    if (returnVal < 0) {
      fprintfError();
    }
  } else {
    fopenError(f, isRead = false);
  }
}

fun fwrite(f: file, args ...?numArgs) {
  for param i in 1..numArgs {
    fwrite(f, args(i));
  }
}

fun fwriteln(f: file, args ...?numArgs) {
  fwrite(f, (...args));
  fwriteln(f);
}

fun fwriteln(f: file) {
  fwrite(f, "\n");
}

fun write(args ...?numArgs) {
  fwrite(stdout, (...args));
}

fun writeln(args ...?numArgs) {
  fwriteln(stdout, (...args));
}

fun writeln() {
  fwriteln(stdout);
}