Skip to content

Commit

Permalink
#74 Start implementing C__new
Browse files Browse the repository at this point in the history
  • Loading branch information
dibyendumajumdar committed Oct 14, 2021
1 parent da68cb0 commit bbb3045
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 4 deletions.
5 changes: 4 additions & 1 deletion include/ravi_compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ enum TokenType {
TOK_defer,
TOK_C__decl,
TOK_C__unsafe,
TOK_C__new,
TOK_nil,
TOK_not,
TOK_or,
Expand Down Expand Up @@ -313,7 +314,8 @@ enum AstNodeType {
EXPR_FUNCTION, /* function literal */
EXPR_TABLE_LITERAL, /* table constructor */
EXPR_FUNCTION_CALL,
EXPR_CONCAT
EXPR_CONCAT,
EXPR_BUILTIN
};

typedef struct Statement Statement;
Expand Down Expand Up @@ -342,6 +344,7 @@ typedef struct TableLiteralExpression TableLiteralExpression;
typedef struct SuffixedExpression SuffixedExpression;
typedef struct FunctionCallExpression FunctionCallExpression;
typedef struct StringConcatenationExpression StringConcatenationExpression;
typedef struct BuiltinExpression BuiltinExpression;

typedef struct Scope Scope;

Expand Down
2 changes: 2 additions & 0 deletions src/ast_lower.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ static void process_expression(CompilerState *container, AstNode *node)
case EXPR_TABLE_LITERAL:
process_expression_list(container, node->table_expr.expr_list);
break;
case EXPR_BUILTIN:
break;
default:
assert(0);
break;
Expand Down
6 changes: 6 additions & 0 deletions src/ast_printer.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,12 @@ void raviX_print_ast_node(TextBuffer *buf, AstNode *node, int level)
printf_buf(buf, "%p%c\n", level, "[concat end]");
break;
}
case EXPR_BUILTIN: {
printf_buf(buf, "%p%c %T\n", level, "C__new(", &node->string_concatenation_expr.type);
// TODO print contents
printf_buf(buf, "%p%c\n", level, ")");
break;
}
default:
printf_buf(buf, "%pUnsupported node type %d\n", level, node->type);
assert(0);
Expand Down
1 change: 1 addition & 0 deletions src/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ static const char *const luaX_tokens[] = {
"defer",
"C__decl",
"C__unsafe",
"C__new",
"nil",
"not",
"or",
Expand Down
1 change: 1 addition & 0 deletions src/linearizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,7 @@ static Pseudo *linearize_expression(Proc *proc, AstNode *expr)
case EXPR_CONCAT: {
result = linearize_concat_expression(proc, expr);
} break;
// FIXME EXPR_BUILTIN
default:
handle_error(proc->linearizer->ast_container, "feature not yet implemented");
break;
Expand Down
47 changes: 46 additions & 1 deletion src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static AstNode *raviX_allocate_ast_node(ParserState *parser, enum AstNodeType ty

static AstNode *allocate_expr_ast_node(ParserState *parser, enum AstNodeType type)
{
assert(type >= EXPR_LITERAL && type <= EXPR_CONCAT);
assert(type >= EXPR_LITERAL && type <= EXPR_BUILTIN);
AstNode *node = raviX_allocate_ast_node(parser, type);
node->common_expr.truncate_results = 0;
set_typecode(&node->common_expr.type, RAVI_TANY);
Expand Down Expand Up @@ -865,13 +865,58 @@ static AstNode *parse_primary_expression(ParserState *parser)
return primary_expr;
}

static AstNode *parse_builtin_expression(ParserState *parser)
{
LexerState *ls = parser->ls;

AstNode *builtin_expr = allocate_expr_ast_node(parser, EXPR_BUILTIN);
builtin_expr->builtin_expr.type.type_code = RAVI_TUSERDATA;
builtin_expr->builtin_expr.type.type_name = NULL;
builtin_expr->builtin_expr.type_name = NULL;
builtin_expr->builtin_expr.type_prefix = NULL;
builtin_expr->builtin_expr.size_expr = NULL;

raviX_next(ls);
checknext(ls, '(');
check(ls, TOK_STRING);
builtin_expr->builtin_expr.type_prefix = ls->t.seminfo.ts;
raviX_next(ls);
checknext(ls, ',');
check(ls, TOK_STRING);
builtin_expr->builtin_expr.type_name = ls->t.seminfo.ts;
raviX_next(ls);
checknext(ls, ',');
builtin_expr->builtin_expr.size_expr = parse_expression(parser);
if (builtin_expr->builtin_expr.size_expr == NULL) {
raviX_syntaxerror(ls, "Expected a size expression as third argument to C__new");
}
checknext(ls, ')');

TextBuffer buf;
uint32_t len = builtin_expr->builtin_expr.type_prefix->len + builtin_expr->builtin_expr.type_name->len;
raviX_buffer_init(&buf, len+ 1);
raviX_buffer_add_string(&buf, builtin_expr->builtin_expr.type_prefix->str);
raviX_buffer_add_string(&buf, ".");
raviX_buffer_add_string(&buf, builtin_expr->builtin_expr.type_name->str);

const StringObject *typename = raviX_create_string(parser->container, buf.buf, buf.pos);
builtin_expr->builtin_expr.type.type_name = typename;

raviX_buffer_free(&buf);

return builtin_expr;
}

/* variable or field access or function call */
static AstNode *parse_suffixed_expression(ParserState *parser)
{
LexerState *ls = parser->ls;
/* suffixedexp ->
primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */
int line = ls->linenumber;
if (ls->t.token == TOK_C__new) {
return parse_builtin_expression(parser);
}
AstNode *suffixed_expr = allocate_expr_ast_node(parser, EXPR_SUFFIXED);
suffixed_expr->suffixed_expr.primary_expr = parse_primary_expression(parser);
suffixed_expr->suffixed_expr.type = suffixed_expr->suffixed_expr.primary_expr->common_expr.type;
Expand Down
8 changes: 8 additions & 0 deletions src/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,13 @@ struct FunctionCallExpression {
AstNodeList *arg_list; /* Call arguments */
int num_results; /* How many results do we expect, -1 means all available results */
};
struct BuiltinExpression {
/* Currently only for C__new but potentially could be other builtins */
BASE_EXPRESSION_FIELDS;
const StringObject *type_prefix; /* Namespace */
const StringObject *type_name; /* Name of the C struct type */
AstNode *size_expr; /* Number of elements of type - > 1 means array */
};
#undef BASE_EXPRESSION_FIELDS

/* ALL AST nodes start with following fields */
Expand Down Expand Up @@ -424,6 +431,7 @@ struct AstNode {
SuffixedExpression suffixed_expr;
FunctionCallExpression function_call_expr;
StringConcatenationExpression string_concatenation_expr;
BuiltinExpression builtin_expr;
};
};
#undef BASE_AST_FIELDS
Expand Down
2 changes: 2 additions & 0 deletions src/typechecker.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,8 @@ static void typecheck_ast_node(CompilerState *container, AstNode *function, AstN
infer_table_type(container, function, node);
break;
}
case EXPR_BUILTIN:
break;
default:
assert(0);
}
Expand Down
10 changes: 9 additions & 1 deletion tests/input/t10_embed_C.in
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ local j: integer = 2

C__unsafe(i,j) [[
long long k = i+j; // Okay as primitive types
]]
]]
#
C__decl [[
typedef struct {
int i;
} MyStruct;
]]

local u = C__new('tt', 'MyStruct', 1)
2 changes: 1 addition & 1 deletion utils/tokenmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define TKDEF(_, __, ___) \
_(and) _(break) _(do) _(else) _(elseif) _(end) \
_(false) _(for) _(function) _(goto) _(if) _(in) _(local) \
_(defer) _(C__decl) _(C__unsafe) /* Ravi extensions */ \
_(defer) _(C__decl) _(C__unsafe) _(C__new) /* Ravi extensions */ \
_(nil) _(not) _(or) \
_(repeat) _(return) _(then) _(true) _(until) _(while) \
/* other terminal symbols */ \
Expand Down

0 comments on commit bbb3045

Please sign in to comment.