Skip to content

Commit

Permalink
[WIP] Allow longer strings, not '\0'-terminated
Browse files Browse the repository at this point in the history
Still to port from ISSOtm's strings branch:
- lexer.c
- parser.y
- symbol.c

Fixes gbdev#650
Fixes gbdev#505
  • Loading branch information
Rangi42 committed Apr 29, 2021
1 parent ee67f10 commit c6f5cde
Show file tree
Hide file tree
Showing 15 changed files with 315 additions and 92 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ rgbasm_obj := \
src/asm/parser.o \
src/asm/rpn.o \
src/asm/section.o \
src/asm/string.o \
src/asm/symbol.o \
src/asm/util.o \
src/asm/warning.o \
Expand Down
8 changes: 5 additions & 3 deletions include/asm/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ struct FormatSpec {
bool valid;
};

struct String;

struct StrFmtArg {
union {
uint32_t number;
char *string;
struct String *string;
};
bool isNumeric;
};
Expand All @@ -57,7 +59,7 @@ bool fmt_IsValid(struct FormatSpec const *fmt);
bool fmt_IsFinished(struct FormatSpec const *fmt);
void fmt_UseCharacter(struct FormatSpec *fmt, int c);
void fmt_FinishCharacters(struct FormatSpec *fmt);
void fmt_PrintString(char *buf, size_t bufLen, struct FormatSpec const *fmt, char const *value);
void fmt_PrintNumber(char *buf, size_t bufLen, struct FormatSpec const *fmt, uint32_t value);
struct String *fmt_PrintString(struct FormatSpec const *fmt, struct String const *value);
struct String *fmt_PrintNumber(struct FormatSpec const *fmt, uint32_t value);

#endif /* RGBDS_FORMAT_SPEC_H */
7 changes: 4 additions & 3 deletions include/asm/fstack.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ struct FileStackNamedNode { /* NODE_FILE, NODE_MACRO */
extern size_t maxRecursionDepth;

struct MacroArgs;
struct String;

void fstk_Dump(struct FileStackNode const *node, uint32_t lineNo);
void fstk_DumpCurrent(void);
Expand All @@ -71,10 +72,10 @@ bool fstk_FindFile(char const *path, char **fullPath, size_t *size);

bool yywrap(void);
void fstk_RunInclude(char const *path);
void fstk_RunMacro(char const *macroName, struct MacroArgs *args);
void fstk_RunMacro(struct String const *macroName, struct MacroArgs *args);
void fstk_RunRept(uint32_t count, int32_t reptLineNo, char *body, size_t size);
void fstk_RunFor(char const *symName, int32_t start, int32_t stop, int32_t step,
int32_t reptLineNo, char *body, size_t size);
void fstk_RunFor(struct String const *symName, int32_t start, int32_t stop, int32_t step,
int32_t reptLineNo, char *body, size_t size);
void fstk_StopRept(void);
bool fstk_Break(void);

Expand Down
2 changes: 0 additions & 2 deletions include/asm/lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

#include <stdbool.h>

#define MAXSTRLEN 255

struct LexerState;
extern struct LexerState *lexerState;
extern struct LexerState *lexerStateEOL;
Expand Down
3 changes: 2 additions & 1 deletion include/asm/section.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
extern uint8_t fillByte;

struct Expression;
struct String;

struct Section {
char *name;
struct String *name;
enum SectionType type;
enum SectionModifier modifier;
struct FileStackNode *src; /* Where the section was defined */
Expand Down
53 changes: 53 additions & 0 deletions include/asm/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* This file is part of RGBDS.
*
* Copyright (c) 2021, Eldred Habert and RGBDS contributors.
*
* SPDX-License-Identifier: MIT
*/

#ifndef RGBDS_STRING_H
#define RGBDS_STRING_H

#include <assert.h>
#include <stdbool.h>
#include <stdint.h>

#include "helpers.h"

struct String;

#define PRI_STR ".*s"
// WARNING: **DO NOT** pass any side-effecting parameters to the macros below!
#define STR_FMT(str) (int)str_Len(str), str_Chars(str)

#define MUTATE_STR(str, ...) do { \
struct String *___orig_str = str; \
str = __VA_ARGS__; \
assert(___orig_str == str); /* This shouldn't have been reallocated */ \
} while (0)

static inline bool str_IsWhitespace(int c)
{
return c == ' ' || c == '\t';
}

size_t str_Len(struct String const *str) pure_;
void str_Trunc(struct String *str, size_t len);
char str_Index(struct String const *str, size_t i) pure_;
bool str_Find(struct String const *str, char c) pure_;
char const *str_Chars(struct String const *str) pure_;

/**
* @param capacity The capacity to use, or 0 if unknown
*/
struct String *str_New(size_t capacity) mallocish_;
void str_Ref(struct String *str);
void str_Unref(struct String *str);

struct String *str_Push(struct String *str, char c) warn_unused_result_;
struct String *str_Append(struct String *lhs, struct String const *rhs) warn_unused_result_;
struct String *str_AppendSlice(struct String *lhs, char const *rhs, size_t len) warn_unused_result_;
void str_TrimEnd(struct String *str);

#endif
49 changes: 25 additions & 24 deletions include/asm/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
#include <time.h>

#include "asm/section.h"
#include "asm/string.h"

#include "platform.h" // MIN_NB_ELMS
#include "types.h"

#define HASHSIZE (1 << 16)
#define MAXSYMLEN 256

enum SymbolType {
SYM_LABEL,
Expand All @@ -32,7 +32,7 @@ enum SymbolType {
};

struct Symbol {
char name[MAXSYMLEN + 1];
struct String *name;
enum SymbolType type;
bool isExported; /* Whether the symbol is to be exported */
bool isBuiltin; /* Whether the symbol is a built-in */
Expand All @@ -45,13 +45,14 @@ struct Symbol {
/* If sym_IsNumeric */
int32_t value;
int32_t (*numCallback)(void);
/* For SYM_MACRO and SYM_EQUS; TODO: have separate fields */
/* For SYM_MACRO */
struct {
size_t macroSize;
char *macro;
};
/* For SYM_EQUS */
char const *(*strCallback)(void);
struct String *str;
struct String *(*strCallback)(void);
};

uint32_t ID; /* ID of the symbol in the object file (-1 if none) */
Expand Down Expand Up @@ -92,7 +93,7 @@ static inline bool sym_IsLabel(struct Symbol const *sym)

static inline bool sym_IsLocal(struct Symbol const *sym)
{
return sym_IsLabel(sym) && strchr(sym->name, '.');
return sym_IsLabel(sym) && str_Find(sym->name, '.');
}

static inline bool sym_IsExported(struct Symbol const *sym)
Expand All @@ -103,49 +104,49 @@ static inline bool sym_IsExported(struct Symbol const *sym)
/*
* Get a string equate's value
*/
static inline char const *sym_GetStringValue(struct Symbol const *sym)
static inline struct String *sym_GetStringValue(struct Symbol const *sym)
{
if (sym->hasCallback)
return sym->strCallback();
return sym->macro;
return sym->str;
}

void sym_ForEach(void (*func)(struct Symbol *, void *), void *arg);

int32_t sym_GetValue(struct Symbol const *sym);
void sym_SetExportAll(bool set);
struct Symbol *sym_AddLocalLabel(char const *symName);
struct Symbol *sym_AddLabel(char const *symName);
struct Symbol *sym_AddLocalLabel(struct String *symName);
struct Symbol *sym_AddLabel(struct String *symName);
struct Symbol *sym_AddAnonLabel(void);
void sym_WriteAnonLabelName(char buf[MIN_NB_ELMS(MAXSYMLEN + 1)], uint32_t ofs, bool neg);
void sym_Export(char const *symName);
struct Symbol *sym_AddEqu(char const *symName, int32_t value);
struct Symbol *sym_AddSet(char const *symName, int32_t value);
struct String *sym_WriteAnonLabelName(uint32_t ofs, bool neg);
void sym_Export(struct String const *symName);
struct Symbol *sym_AddEqu(struct String const *symName, int32_t value);
struct Symbol *sym_AddSet(struct String const *symName, int32_t value);
uint32_t sym_GetPCValue(void);
uint32_t sym_GetConstantSymValue(struct Symbol const *sym);
uint32_t sym_GetConstantValue(char const *symName);
uint32_t sym_GetConstantValue(struct String const *symName);
/*
* Find a symbol by exact name, bypassing expansion checks
*/
struct Symbol *sym_FindExactSymbol(char const *symName);
struct Symbol *sym_FindExactSymbol(struct String const *symName);
/*
* Find a symbol by exact name; may not be scoped, produces an error if it is
*/
struct Symbol *sym_FindUnscopedSymbol(char const *symName);
struct Symbol *sym_FindUnscopedSymbol(struct String const *symName);
/*
* Find a symbol, possibly scoped, by name
*/
struct Symbol *sym_FindScopedSymbol(char const *symName);
struct Symbol *sym_FindScopedSymbol(struct String const *symName);
struct Symbol const *sym_GetPC(void);
struct Symbol *sym_AddMacro(char const *symName, int32_t defLineNo, char *body, size_t size);
struct Symbol *sym_Ref(char const *symName);
struct Symbol *sym_AddString(char const *symName, char const *value);
struct Symbol *sym_RedefString(char const *symName, char const *value);
void sym_Purge(char const *symName);
struct Symbol *sym_AddMacro(struct String *symName, int32_t defLineNo, char *body, size_t size);
struct Symbol *sym_Ref(struct String *symName);
struct Symbol *sym_AddString(struct String *symName, struct String *value);
struct Symbol *sym_RedefString(struct String *symName, struct String *value);
void sym_Purge(struct String const *symName);
void sym_Init(time_t now);

/* Functions to save and restore the current symbol scope. */
char const *sym_GetCurrentSymbolScope(void);
void sym_SetCurrentSymbolScope(char const *newScope);
struct String const *sym_GetCurrentSymbolScope(void);
void sym_SetCurrentSymbolScope(struct String const *newScope);

#endif /* RGBDS_SYMBOL_H */
1 change: 0 additions & 1 deletion include/asm/warning.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ enum WarningID {
WARNING_EMPTY_MACRO_ARG, /* Empty macro argument */
WARNING_EMPTY_STRRPL, /* Empty second argument in `STRRPL` */
WARNING_LARGE_CONSTANT, /* Constants too large */
WARNING_LONG_STR, /* String too long for internal buffers */
WARNING_MACRO_SHIFT, /* Shift past available arguments in macro */
WARNING_NESTED_COMMENT, /* Comment-start delimiter in a block comment */
WARNING_OBSOLETE, /* Obsolete things */
Expand Down
9 changes: 9 additions & 0 deletions include/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
#ifdef __GNUC__ // GCC or compatible
#define format_(archetype, str_index, first_arg) \
__attribute__ ((format (archetype, str_index, first_arg)))
// Notes that a function allocates something
#define mallocish_ __attribute__ ((malloc))
// Notes that a function does not have any side effects (more or less)
#define pure_ __attribute__ ((pure))
// Notes that a function's return value should not be ignored
#define warn_unused_result_ __attribute__ ((warn_unused_result))
// In release builds, define "unreachable" as such, but trap in debug builds
#ifdef NDEBUG
#define unreachable_ __builtin_unreachable
Expand All @@ -27,6 +33,9 @@
#else
// Unsupported, but no need to throw a fit
#define format_(archetype, str_index, first_arg)
#define mallocish_
#define pure_
#define warn_unused_result_
// This seems to generate similar code to __builtin_unreachable, despite different semantics
// Note that executing this is undefined behavior (declared _Noreturn, but does return)
static inline _Noreturn unreachable_(void) {}
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ set(rgbasm_src
"asm/output.c"
"asm/rpn.c"
"asm/section.c"
"asm/string.c"
"asm/symbol.c"
"asm/util.c"
"asm/warning.c"
Expand Down
Loading

0 comments on commit c6f5cde

Please sign in to comment.