CGrammar improvements:

- show return type if _Noreturn function has type other than void
  - improve translation of function body
  - replace "Let `i` be an int" with "Declare `i` as an int"
This commit is contained in:
Pragmatic Software 2014-07-04 12:18:59 +00:00
parent 1f3533bf76
commit 9b93a33acf
3 changed files with 42 additions and 18 deletions

View File

@ -13,7 +13,7 @@ use warnings;
# These are set automatically by the build/commit script
use constant {
BUILD_NAME => "PBot",
BUILD_REVISION => 702,
BUILD_REVISION => 703,
BUILD_DATE => "2014-07-04",
};

View File

@ -19,7 +19,7 @@ if($code =~ s/^-f\s+//) {
}
my ($has_function, $has_main, $got_nomain);
my $prelude_base = "#define _XOPEN_SOURCE 9001\n#define __USE_XOPEN\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n#include <errno.h>\n#include <ctype.h>\n#include <assert.h>\n\n";
my $prelude_base = "#define _XOPEN_SOURCE 9001\n#define __USE_XOPEN\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <math.h>\n#include <limits.h>\n#include <sys/types.h>\n#include <stdint.h>\n#include <errno.h>\n#include <ctype.h>\n#include <assert.h>\n#include <stdnoreturn.h>\n#include <stdbool.h>\n\n";
my $prelude = $prelude_base;
print "code before: [$code]\n" if $debug;
@ -275,7 +275,7 @@ if($lang eq 'C89' or $lang eq 'C99' or $lang eq 'C11' or $lang eq 'C++') {
$precode =~ s/^{(.*)}$/$1/s;
if(not $has_main and not $got_nomain) {
$code = "$prelude\n$code" . "int main(void) {\n$precode\n;\nreturn 0;\n}\n";
$code = "$prelude\n$code" . "int main(void) {\n$precode\n;\n}\n";
} else {
print "code: [$code]; precode: [$precode]\n" if $debug;
$code = "$prelude\n$precode\n\n$code\n";
@ -389,14 +389,17 @@ close $fh;
$output = `./c2eng.pl code2eng.c` if not defined $output;
if(not $has_function and not $has_main) {
$output =~ s/Let .main. be a function taking no arguments and returning int.\s*To perform the function.\s*(return 0.)?//i;
$output =~ s/Let .main. be a function taking no arguments and returning int.\s*When called, the function will.\s*(return 0.)?//i;
$output =~ s/\s*Return 0.\s*End of function .main..\s*//;
$output =~ s/\s*Return 0.$//;
$output =~ s/\s*Finally, return 0.$//;
$output =~ s/\s*and then return 0.$/./;
$output =~ s/\s*Do nothing.\s*$//;
$output =~ s/^\s*(.)/\U$1/;
$output =~ s/\.\s+(\S)/. \U$1/g;
} elsif($has_function and not $has_main) {
$output =~ s/\s*Let `main` be a function taking no arguments and returning int.\s*To perform the function, return 0.//;
$output =~ s/\s*Let `main` be a function taking no arguments and returning int.\s*When called, the function will return 0.//;
$output =~ s/\s*Finally, return 0.$//;
$output =~ s/\s*and then return 0.$/./;
}
$output =~ s/\s+/ /;

View File

@ -162,20 +162,37 @@ function_definition:
$parameter_list =~ s/function/function with suggestion to be as fast as possible$and/;
}
if ($declaration_specifiers =~ /_Noreturn/) {
if ($return_type =~ s/_Noreturn//g) {
$return_type = join(' ', split(' ', $return_type));
$parameter_list =~ s/ returning$//;
$return_type = "which doesn't return to its caller";
if ($return_type eq 'void') {
$return_type = "which doesn't return to its caller";
} else {
$return_type = "which shouldn't return to its caller yet does mysteriously return $return_type";
}
}
$return = "\nLet $name be a ";
$return .= $parameter_list;
$return .= " $return_type.\nTo perform the function, ^L";
$return .= join('', @{$item{'compound_statement(?)'}});
$return = "\nLet $name be a $parameter_list $return_type.\n";
my $statements = join('', @{$item{'compound_statement(?)'}});
$return .= "When called, the function will ^L$statements";
}
block_item_list:
block_item(s)
{ $return = join('', @{$item{'block_item(s)'}}); }
{
if (@{$item{'block_item(s)'}} == 1) {
$return = $item{'block_item(s)'}->[0];
} elsif (@{$item{'block_item(s)'}} == 2) {
my $first = $item{'block_item(s)'}->[0];
my $second = $item{'block_item(s)'}->[1];
$first =~ s/\.?\s*$//;
$return = "$first and then ^L$second";
} else {
my $last = pop @{$item{'block_item(s)'}};
$return = join('Then ^L', @{$item{'block_item(s)'}}) . "Finally, ^L$last";
}
}
block_item:
declaration
@ -629,7 +646,11 @@ declaration:
$item{declaration_specifiers} = join(' ', split(' ', $item{declaration_specifiers}));
if ($noreturn) {
$item{declaration_specifiers} = "which doesn't return to its caller";
if($item{declaration_specifiers} eq 'void') {
$item{declaration_specifiers} = "which doesn't return to its caller";
} else {
$item{declaration_specifiers} = "which shouldn't return to its caller yet does mysteriously return $item{declaration_specifiers}";
}
}
my $inits = 0;
@ -637,9 +658,9 @@ declaration:
$inits++;
if (not $arg{context} eq 'struct member') {
if ($arg{context} eq 'for init') {
$return .= "letting ";
$return .= "declaring ";
} else {
$return .= "Let ";
$return .= "Declare ";
}
}
@ -753,10 +774,10 @@ declaration:
if ($typedef) {
$return .= ' each' if @identifiers > 1;
$return .= ' be another name for ';
$return .= ' as another name for ';
push @typedefs, @identifiers;
} else {
$return .= ' be ';
$return .= ' as ';
}
if ($first_qualifier) {