Fixes to broken docs parsing. Fixes #880.

This commit is contained in:
Christoffer Lerno
2023-07-25 17:46:51 +02:00
committed by Christoffer Lerno
parent d0c00b859b
commit b74b62e242
5 changed files with 62 additions and 64 deletions

View File

@@ -182,7 +182,7 @@ macro bool os_is_posix()
/**
* @param [&in] name
* @param [in] name
* @require name.len > 0
**/
fn String! get_var(String name)
@@ -200,8 +200,8 @@ fn String! get_var(String name)
/**
* @param [&in] name
* @param [&in] value
* @param [in] name
* @param [in] value
* @require name.len > 0
**/
fn void set_var(String name, String value, bool overwrite = true)
@@ -218,7 +218,7 @@ fn void set_var(String name, String value, bool overwrite = true)
}
/**
* @param [&in] name
* @param [in] name
* @require name.len > 0
**/
fn void clear_var(String name)

View File

@@ -53,19 +53,19 @@ fn void! File.memopen(File* file, char[] data, String mode)
/**
* @require file && file.file != null
* @require self.file != null
*/
fn void! File.putc(File *file, char c)
fn void! File.putc(self, char c)
{
if (!libc::fputc(c, file.file)) return IoError.EOF?;
if (!libc::fputc(c, self.file)) return IoError.EOF?;
}
/**
* @require file != null
* @param [&inout] self
*/
fn void! File.close(File *file) @inline
fn void! File.close(&self) @inline
{
if (file.file && libc::fclose(file.file))
if (self.file && libc::fclose(self.file))
{
switch (libc::errno())
{
@@ -83,67 +83,63 @@ fn void! File.close(File *file) @inline
default: return IoError.UNKNOWN_ERROR?;
}
}
file.file = null;
self.file = null;
}
/**
* @require file && file.file
* @require self.file
*/
fn bool File.eof(File* file) @inline
fn bool File.eof(self) @inline
{
return libc::feof(file.file) != 0;
return libc::feof(self.file) != 0;
}
/**
* @param [in] buffer
*/
fn usz! File.read(File* file, char[] buffer)
fn usz! File.read(self, char[] buffer)
{
return os::native_fread(file.file, buffer);
return os::native_fread(self.file, buffer);
}
/**
* @param [&in] file
* @param [&out] buffer
* @require file.file `File must be initialized`
* @param [out] buffer
* @require self.file `File must be initialized`
*/
fn usz! File.write(File file, char[] buffer)
fn usz! File.write(self, char[] buffer)
{
return os::native_fwrite(file.file, buffer);
return os::native_fwrite(self.file, buffer);
}
/**
* @param [&in] file
* @require file.file `File must be initialized`
* @require self.file `File must be initialized`
*/
fn usz! File.printn(File file, String string = "")
fn usz! File.printn(self, String string = "")
{
usz len = file.print(string)!;
if (!libc::putc('\n', file.file)) return IoError.UNKNOWN_ERROR?;
usz len = self.print(string)!;
if (!libc::putc('\n', self.file)) return IoError.UNKNOWN_ERROR?;
return len + 1;
}
/**
* @param [&in] file
* @require file.file `File must be initialized`
* @require self.file `File must be initialized`
*/
fn usz! File.print(File file, String string)
fn usz! File.print(self, String string)
{
usz len = string.len;
if (len != file.write((char[])string)!) return IoError.UNKNOWN_ERROR?;
if (len != self.write((char[])string)!) return IoError.UNKNOWN_ERROR?;
return len;
}
/**
* @param [&in] file
* @require file.file `File must be initialized`
* @require self.file `File must be initialized`
*/
fn DString File.getline(File* file, Allocator* using = mem::heap())
fn DString File.getline(self, Allocator* using = mem::heap())
{
DString s = dstring::new_with_capacity(120, using);
while (!file.eof())
while (!self.eof())
{
int c = libc::fgetc(file.file);
int c = libc::fgetc(self.file);
if (c == -1) break;
if (c == '\n') break;
s.append_char((char)c);
@@ -152,27 +148,25 @@ fn DString File.getline(File* file, Allocator* using = mem::heap())
}
/**
* @param [&in] file
* @require file.file `File must be initialized`
* @require self.file `File must be initialized`
* @return "a zero terminated String (the pointer may be safely cast into a ZString)"
*/
fn String File.tgetline(File* file)
fn String File.tgetline(self)
{
return file.getline(mem::temp()).zstr().as_str();
return self.getline(mem::temp()).zstr().as_str();
}
fn char! File.getc(File* file)
fn char! File.getc(self)
{
int c = libc::fgetc(file.file);
int c = libc::fgetc(self.file);
if (c == -1) return IoError.EOF?;
return (char)c;
}
/**
* @param [&in] file
* @require file.file `File must be initialized`
* @require self.file `File must be initialized`
*/
fn void File.flush(File* file)
fn void File.flush(self)
{
libc::fflush(file.file);
libc::fflush(self.file);
}

View File

@@ -137,7 +137,6 @@ fn bool Path.equals(self, Path p2)
/**
* Append the string to the current path.
*
* @param [in] path
* @param [in] filename
* @ensure return.path_string.len >= self.path_string.len
**/

View File

@@ -2375,11 +2375,20 @@ static inline bool parse_import(ParseContext *c)
}
INLINE void append_docs(AstId **next, AstId *first, Ast *new_doc)
{
if (!*first)
{
*first = astid(new_doc);
}
**next = astid(new_doc);
*next = &new_doc->next;
}
/**
* contract ::= expression_list (':'? STRING)?
*/
static inline bool parse_doc_contract(ParseContext *c, AstId **docs_ref, ContractKind kind)
static inline bool parse_doc_contract(ParseContext *c, AstId *docs, AstId **docs_next, ContractKind kind)
{
Ast *ast = ast_new_curr(c, AST_CONTRACT);
ast->contract.kind = kind;
@@ -2426,8 +2435,7 @@ static inline bool parse_doc_contract(ParseContext *c, AstId **docs_ref, Contrac
scratch_buffer_append(".");
ast->contract.contract.expr_string = scratch_buffer_copy();
}
**docs_ref = astid(ast);
*docs_ref = &ast->next;
append_docs(docs_next, docs, ast);
return true;
}
@@ -2435,7 +2443,7 @@ static inline bool parse_doc_contract(ParseContext *c, AstId **docs_ref, Contrac
* param_contract ::= '@param' inout_attribute? any_identifier ( (':' STRING) | STRING )?
* inout_attribute ::= '[' '&'? ('in' | 'inout' | 'out') ']'
*/
static inline bool parse_contract_param(ParseContext *c, AstId **docs_ref)
static inline bool parse_contract_param(ParseContext *c, AstId *docs, AstId **docs_next)
{
Ast *ast = ast_new_curr(c, AST_CONTRACT);
ast->contract.kind = CONTRACT_PARAM;
@@ -2497,12 +2505,11 @@ static inline bool parse_contract_param(ParseContext *c, AstId **docs_ref)
{
try_consume(c, TOKEN_STRING);
}
**docs_ref = astid(ast);
*docs_ref = &ast->next;
append_docs(docs_next, docs, ast);
return true;
}
static inline bool parse_doc_optreturn(ParseContext *c, AstId **docs_ref)
static inline bool parse_doc_optreturn(ParseContext *c, AstId *docs, AstId **docs_next)
{
Ast **returns = NULL;
Ast *ast = ast_new_curr(c, AST_CONTRACT);
@@ -2531,8 +2538,7 @@ static inline bool parse_doc_optreturn(ParseContext *c, AstId **docs_ref)
// Just ignore our potential string:
(void)try_consume(c, TOKEN_STRING);
ast->contract.faults = returns;
**docs_ref = astid(ast);
*docs_ref = &ast->next;
append_docs(docs_next, docs, ast);
return true;
}
@@ -2542,7 +2548,7 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref)
*contracts_ref = 0;
if (!try_consume(c, TOKEN_DOCS_START)) return true;
AstId *last = contracts_ref;
AstId **next = &contracts_ref;
uint32_t row_last_row = c->span.row;
while (1)
{
@@ -2555,7 +2561,7 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref)
const char *name = symstr(c);
if (name == kw_at_param)
{
if (!parse_contract_param(c, &last)) return false;
if (!parse_contract_param(c, contracts_ref, next)) return false;
break;
}
else if (name == kw_at_return)
@@ -2563,7 +2569,7 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref)
advance(c);
if (tok_is(c, TOKEN_BANG))
{
if (!parse_doc_optreturn(c, &contracts_ref)) return false;
if (!parse_doc_optreturn(c, contracts_ref, next)) return false;
break;
}
if (!consume(c, TOKEN_STRING, "Expected a string description.")) return false;
@@ -2578,25 +2584,24 @@ static bool parse_contracts(ParseContext *c, AstId *contracts_ref)
}
else if (name == kw_at_require)
{
if (!parse_doc_contract(c, &contracts_ref, CONTRACT_REQUIRE)) return false;
if (!parse_doc_contract(c, contracts_ref, next, CONTRACT_REQUIRE)) return false;
break;
}
else if (name == kw_at_checked)
{
if (!parse_doc_contract(c, &contracts_ref, CONTRACT_CHECKED)) return false;
if (!parse_doc_contract(c, contracts_ref, next, CONTRACT_CHECKED)) return false;
break;
}
else if (name == kw_at_ensure)
{
if (!parse_doc_contract(c, &contracts_ref, CONTRACT_ENSURE)) return false;
if (!parse_doc_contract(c, contracts_ref, next, CONTRACT_ENSURE)) return false;
break;
}
else if (name == kw_at_pure)
{
Ast *ast = ast_new_curr(c, AST_CONTRACT);
ast->contract.kind = CONTRACT_PURE;
*contracts_ref = astid(ast);
contracts_ref = &ast->next;
append_docs(next, contracts_ref, ast);
advance(c);
break;
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.580"
#define COMPILER_VERSION "0.4.581"