Implement character escape sequences
This commit is contained in:
parent
156506e8fa
commit
0dc95d4466
34
example.elna
34
example.elna
@ -12,6 +12,9 @@ type
|
||||
dummy: Int
|
||||
end;
|
||||
|
||||
const
|
||||
SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2;
|
||||
|
||||
proc test_array();
|
||||
var a: T, x: Int;
|
||||
begin
|
||||
@ -66,19 +69,6 @@ begin
|
||||
end
|
||||
end;
|
||||
|
||||
proc test_not();
|
||||
var x: Bool;
|
||||
begin
|
||||
x := false;
|
||||
|
||||
writei("");
|
||||
if not x then
|
||||
writei("Test not true.")
|
||||
else
|
||||
writei("Test not false")
|
||||
end
|
||||
end;
|
||||
|
||||
proc test_param(d: Int, e: Int);
|
||||
begin
|
||||
writei("");
|
||||
@ -124,14 +114,14 @@ proc fseek(stream: pointer to FILE, off: Int, whence: Int): Int; extern;
|
||||
proc ftell(stream: pointer to FILE): Int; extern;
|
||||
proc fread(ptr: pointer to Char, size: Int, nmemb: Int, stream: pointer to FILE): Int; extern;
|
||||
proc write(fd: Int, buf: pointer to Char, count: Int): Int; extern;
|
||||
|
||||
proc malloc(size: Int): pointer to Char; extern;
|
||||
proc free(ptr: pointer to Char); extern;
|
||||
proc calloc(nmemb: Int, size: Int): pointer to Char; extern;
|
||||
|
||||
proc memset(ptr: pointer to Char, c: Int, n: Int): pointer to Char; extern;
|
||||
|
||||
proc read_source(filename: String): pointer to Char;
|
||||
const
|
||||
-- Bug: The procedure doesn't see global constants.
|
||||
SEEK_SET = 0, SEEK_CUR = 1, SEEK_END = 2;
|
||||
var
|
||||
input_file: pointer to FILE,
|
||||
source_size: Int,
|
||||
@ -143,8 +133,7 @@ begin
|
||||
source_size := ftell(input_file);
|
||||
fseek(input_file, 0, SEEK_SET);
|
||||
|
||||
input := malloc(source_size + 1);
|
||||
memset(input, 0, source_size + 1);
|
||||
input := calloc(source_size + 1, 1);
|
||||
fread(input, source_size, 1, input_file);
|
||||
|
||||
fclose(input_file);
|
||||
@ -152,12 +141,6 @@ begin
|
||||
return input
|
||||
end;
|
||||
|
||||
-- Bug: "while not is_eof(…) do" is a syntax error.
|
||||
proc is_not_eof(buffer: pointer to Int): Bool;
|
||||
begin
|
||||
return buffer^ /= 0
|
||||
end;
|
||||
|
||||
proc compile();
|
||||
var
|
||||
input: pointer to Char,
|
||||
@ -166,7 +149,7 @@ begin
|
||||
input := read_source("example.elna");
|
||||
|
||||
input_pointer := input;
|
||||
while is_not_eof(input_pointer) do
|
||||
while input_pointer^ /= '\0' do
|
||||
write(0, input_pointer, 1);
|
||||
input_pointer := input_pointer + 1
|
||||
end;
|
||||
@ -179,7 +162,6 @@ begin
|
||||
test_array();
|
||||
test_record();
|
||||
test_if();
|
||||
test_not();
|
||||
test_param(8, 7);
|
||||
test_const_char();
|
||||
writei(test_return_int());
|
||||
|
@ -124,11 +124,14 @@ namespace gcc
|
||||
|
||||
void generic_visitor::visit(source::program *program)
|
||||
{
|
||||
for (const auto definition : program->value_definitions)
|
||||
{
|
||||
definition->accept(this);
|
||||
}
|
||||
for (const auto& constant : program->type_definitions)
|
||||
{
|
||||
constant->accept(this);
|
||||
}
|
||||
|
||||
tree parameter_types[] = {
|
||||
integer_type_node,
|
||||
build_pointer_type(build_pointer_type(char_type_node))
|
||||
@ -141,10 +144,6 @@ namespace gcc
|
||||
|
||||
enter_scope();
|
||||
|
||||
for (const auto definition : program->value_definitions)
|
||||
{
|
||||
definition->accept(this);
|
||||
}
|
||||
for (const auto body_statement : program->body)
|
||||
{
|
||||
body_statement->accept(this);
|
||||
|
@ -736,7 +736,7 @@ namespace source
|
||||
|
||||
public:
|
||||
unary_expression(const struct position position, expression *operand,
|
||||
const unsigned char operation);
|
||||
const unary_operator operation);
|
||||
|
||||
virtual void accept(parser_visitor *visitor) override;
|
||||
expression& operand();
|
||||
|
@ -41,6 +41,8 @@ namespace source
|
||||
{
|
||||
public:
|
||||
using symbol_ptr = std::shared_ptr<info<T>>;
|
||||
using iterator = typename std::unordered_map<std::string, symbol_ptr>::iterator;
|
||||
using const_iterator = typename std::unordered_map<std::string, symbol_ptr>::const_iterator;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, symbol_ptr> entries;
|
||||
@ -57,6 +59,26 @@ namespace source
|
||||
{
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return entries.begin();
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return entries.end();
|
||||
}
|
||||
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return entries.cbegin();
|
||||
}
|
||||
|
||||
const_iterator cend() const
|
||||
{
|
||||
return entries.cend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for symbol in the table by name. Returns nullptr if the symbol
|
||||
* can not be found.
|
||||
|
@ -752,20 +752,9 @@ namespace source
|
||||
}
|
||||
|
||||
unary_expression::unary_expression(const struct position position, expression *operand,
|
||||
const unsigned char operation)
|
||||
: expression(position), m_operand(std::move(operand))
|
||||
const unary_operator operation)
|
||||
: expression(position), m_operand(std::move(operand)), m_operator(operation)
|
||||
{
|
||||
switch (operation)
|
||||
{
|
||||
case '@':
|
||||
this->m_operator = unary_operator::reference;
|
||||
break;
|
||||
case '!':
|
||||
this->m_operator = unary_operator::negation;
|
||||
break;
|
||||
default:
|
||||
__builtin_unreachable();
|
||||
}
|
||||
}
|
||||
|
||||
void unary_expression::accept(parser_visitor *visitor)
|
||||
|
@ -112,13 +112,50 @@ return {
|
||||
[0-9]+\.[0-9] {
|
||||
return yy::parser::make_FLOAT(strtof(yytext, NULL), this->location);
|
||||
}
|
||||
'[^']' {
|
||||
return yy::parser::make_CHARACTER(
|
||||
std::string(yytext, 1, strlen(yytext) - 2), this->location);
|
||||
'[[:print:]]' {
|
||||
if (yytext[1] == '\\')
|
||||
{
|
||||
REJECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return yy::parser::make_CHARACTER(std::string(yytext, 1, 1), this->location);
|
||||
}
|
||||
}
|
||||
'\\[0nabtfrv\\'"?]' {
|
||||
switch (yytext[2])
|
||||
{
|
||||
case 'n':
|
||||
return yy::parser::make_CHARACTER(std::string("\n"), this->location);
|
||||
case 'a':
|
||||
return yy::parser::make_CHARACTER(std::string("\a"), this->location);
|
||||
case 'b':
|
||||
return yy::parser::make_CHARACTER(std::string("\b"), this->location);
|
||||
case 't':
|
||||
return yy::parser::make_CHARACTER(std::string("\t"), this->location);
|
||||
case 'f':
|
||||
return yy::parser::make_CHARACTER(std::string("\f"), this->location);
|
||||
case 'r':
|
||||
return yy::parser::make_CHARACTER(std::string("\r"), this->location);
|
||||
case 'v':
|
||||
return yy::parser::make_CHARACTER(std::string("\v"), this->location);
|
||||
case '\\':
|
||||
return yy::parser::make_CHARACTER(std::string("\\"), this->location);
|
||||
case '\'':
|
||||
return yy::parser::make_CHARACTER(std::string("'"), this->location);
|
||||
case '"':
|
||||
return yy::parser::make_CHARACTER(std::string("\""), this->location);
|
||||
case '?':
|
||||
return yy::parser::make_CHARACTER(std::string("\?"), this->location);
|
||||
case '0':
|
||||
return yy::parser::make_CHARACTER(std::string("\0", 1), this->location);
|
||||
default:
|
||||
REJECT;
|
||||
}
|
||||
}
|
||||
\"[^\"]*\" {
|
||||
return yy::parser::make_STRING(
|
||||
std::string(yytext, 1, strlen(yytext) - 2), this->location);
|
||||
std::string(yytext, 1, strlen(yytext) - 2), this->location);
|
||||
}
|
||||
\( {
|
||||
return yy::parser::make_LEFT_PAREN(this->location);
|
||||
|
@ -227,6 +227,7 @@ literal:
|
||||
pointer:
|
||||
literal { $$ = $1; }
|
||||
| designator_expression { $$ = $1; }
|
||||
| call_expression { $$ = $1; }
|
||||
| LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); }
|
||||
summand:
|
||||
factor { $$ = std::move($1); }
|
||||
@ -243,11 +244,13 @@ summand:
|
||||
factor:
|
||||
AT pointer
|
||||
{
|
||||
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $2, '@');
|
||||
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $2,
|
||||
elna::source::unary_operator::reference);
|
||||
}
|
||||
| NOT pointer
|
||||
{
|
||||
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $2, '!');
|
||||
$$ = new elna::source::unary_expression(elna::source::make_position(@1), $2,
|
||||
elna::source::unary_operator::negation);
|
||||
}
|
||||
| pointer { $$ = $1; }
|
||||
comparand:
|
||||
@ -296,7 +299,6 @@ expression:
|
||||
$$ = new elna::source::binary_expression(elna::source::make_position(@1), $1, $3, 'o');
|
||||
}
|
||||
| logical_operand { $$ = $1; }
|
||||
| call_expression { $$ = $1; }
|
||||
expressions:
|
||||
expression COMMA expressions
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user