11
\$\begingroup\$

This is an implementation of the Nothing programming language. The language spec is as follows:

Design philosophy

In the current software industry focus lays on solving complex problems by using complicated algorithms. The language "Nothing" was created to shift this focus from complex problems towards the expectations of the programmer and the user. This way even the most complicated programming challenges swiftly disappear as if they never have existed before. Basically, the main strengths of the language "Nothing" are:

  • to create bug-free and portable software https://esolangs.org/wiki/Nothing
  • to shift focus from complex technical solutions towards the expectation of the programmers and users

Program structure

Nothing has a very simple and straightforward structure. It is a typeless language which does not use any of the known programming constructs like loops, choices and the like. It is the only language which can be considered 1GL, 2GL, 3GL, 4GL and 5GL all at the same time.

What I would like to know:

  • Does my program conform to the language specs?
  • Does it follow the design philosophy?
  • Readability, performance, etc. Any improvements welcome

Source code:

/*
 * A 'Nothing' compiler
 * <http://www.turtle.dds.nl/nothing/>
 * September 2010, RoPe Development Inc.
 *
 * Author: authorname
 */

#include <iostream>
#include <fstream>
#include <cstdlib> // EXIT_FAILURE
#include <string> // std::char_traits<char>::eof

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        std::cerr << "nothing: fatal error: no input files\n";
        std::cerr << "compilation terminated.";
        return EXIT_FAILURE;
    }

    std::ifstream program(argv[1]);

    if (!program)
    {
        std::cerr << "nothing: error: " << argv[1] << ": No such file or directory\n";
        std::cerr << "nothing: fatal error: no input files\n";
        std::cerr << "compilation terminated.";        
        return EXIT_FAILURE;
    }

    if (program.peek() != std::char_traits<char>::eof())
    {
        std::cerr << "nothing: fatal error: program is not empty\n";
        std::cerr << "compilation terminated.";
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

Example:

# bash
$ touch helloworld.not
$ ./nothing helloworld.not
$ 
\$\endgroup\$
  • \$\begingroup\$ Why not print a newline at the end of all error messages? \$\endgroup\$ – janos Aug 29 '15 at 16:39
  • 1
    \$\begingroup\$ This question is being discussed on Meta. \$\endgroup\$ – 200_success Aug 29 '15 at 19:24
  • 3
    \$\begingroup\$ I'm confused. You tagged this question as compiler, yet it doesn't generate an executable. Is it really an interpreter? \$\endgroup\$ – 200_success Aug 29 '15 at 21:07
  • \$\begingroup\$ @200_success I can't modify the question now. I could follow the reference implementation and use chmod from sys/stat.h on an empty file. \$\endgroup\$ – user82302 Aug 29 '15 at 21:27
  • \$\begingroup\$ @200_success I thought about using a library to create ELF files...but then my compiler wouldn't be so portable anymore. :| \$\endgroup\$ – user82302 Aug 29 '15 at 21:54
8
\$\begingroup\$

This line here:

return EXIT_SUCCESS

Is equivalent to this:

return 0;

Which is automatically inserted by the compiler if it isn't found. In short, return EXIT_SUCCESS can be removed.

In addition, a few of your error messages don't include a newline at the end, as seen in this line here, and two other places:

std::cerr << "compilation terminated.";

I'd just add a newline to the end of the output string to not annoy the user when the program completes/fails, like this:

std::cerr << "compilation terminated.\n";

Instead of requiring the user to provide a file in the command line arguments, you can just do, well, nothing. This is the language Nothing after all. This means that this piece of code here:

if (argc < 2)
{
    std::cerr << "nothing: fatal error: no input files\n";
    std::cerr << "compilation terminated.";
    return EXIT_FAILURE;
}

Can just become this:

if (argc < 2)
{
    return 0;
}

Other than those two nitpicks, there really isn't much else for me to review here. As far as I can tell, you've followed the language specification just fine, and produced some readable code.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ In C++, it is often common to use << "message" << endl; to add a line break to the code. \$\endgroup\$ – SirPython Aug 29 '15 at 17:17
  • 1
    \$\begingroup\$ @SirPython std::endl flushes the output buffer, and "\n" doesn't. I'm assuming the OP doesn't want that. stackoverflow.com/questions/213907/c-stdendl-vs-n \$\endgroup\$ – Ethan Bierlein Aug 29 '15 at 17:23
  • 1
    \$\begingroup\$ @SirPython It's redundant because I'm using std::cerr \$\endgroup\$ – user82302 Aug 29 '15 at 17:24
5
\$\begingroup\$
  • Don't hardcode the error message. Failure to open a stream is not necessarily due to no such file or directory; you may have insufficient privileges, for example. Use perror().

  • There is no reason to compile just one file at a time.

  • There's no reason to restrict the program to files on disk. It would be nice to be able to use it in pipeline.

  • The --silent option to suppress error messages is always nice to have.

  • Localization is a must! Not everybody reads English.

  • help is missing.

  • For more details, visit GNU Hello World page.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Disclaimer: I know Nothing about C++

Inside the !program if, you seem to have forgotten this line:

std::cerr << "nothing: fatal error: no input files\n";

Which is also present on the if (argc < 2) block. Probably a copy-paste mistake?


Since your error messages are almost always the same, you could make a function to show the error message. Like this:

void show_error(std::string message)
{
    std::cerr << "nothing: fatal error: " << message << "\n";
    std::cerr << "compilation terminated.\n";
}

You have the following line:

std::ifstream program(argv[1]);

The first time I read this, I though: Why is he making a new program? But after some teaching, I've found out it is an object.

The if (!program) block really confused me. I couldn't get why you were checking if there isn't a program.

Since this is a compiler/interpreter, you need code. My suggestion: rename it to code or file. Both would be so much obvious than program. It isn't a bad name! It just isn't the best one.

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ I would take that second recommendation one step further by exiting out of the application with an EXIT_FAILURE. \$\endgroup\$ – SirPython Aug 29 '15 at 18:09
  • \$\begingroup\$ @SirPython That's completelly outside my severelly limited knowledge, but a really good idea. I though about it but gave up. \$\endgroup\$ – Ismael Miguel Aug 29 '15 at 18:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.