aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ek/ast.h76
-rw-r--r--include/ek/ops.h10
-rw-r--r--include/ek/scope.h284
3 files changed, 44 insertions, 326 deletions
diff --git a/include/ek/ast.h b/include/ek/ast.h
index e078f59..201b746 100644
--- a/include/ek/ast.h
+++ b/include/ek/ast.h
@@ -32,18 +32,17 @@
#define AST_ARR_ACCESS(x) x->_arr_access
#define AST_MACRO_CONSTRUCT(x) x->_macro_construct
#define AST_MACRO_EXPAND(x) x->_macro_expand
-#define AST_TYPE_CONSTRUCT(x) x->_type_construct
#define AST_TYPE_EXPAND(x) x->_type_expand
#define AST_TYPE(x) x->_type
#define AST_ID_TYPE(x) x->_type._id
+#define AST_CONSTRUCT_TYPE(x) x->_type._construct
#define AST_TRAIT_TYPE(x) x->_type._trait
/** @todo is sign and proc type the same ? */
-#define AST_TYPEOF_TYPE(x) x->_type._typeof
-#define AST_PROC_TYPE(x) x->_type._proc
+#define AST_PROC_TYPE(x) x->_type._proc
#define AST_ARR_TYPE(x) x->_type._arr
-#define AST_SIGN_TYPE(x) x->_type._sign
-#define AST_ENUM_TYPE(x) x->_type._enum
+#define AST_SIGN_TYPE(x) x->_type._sign
+#define AST_ENUM_TYPE(x) x->_type._enum
#define AST_UNION_TYPE(x) x->_type._union
#define AST_STRUCT_TYPE(x) x->_type._struct
/* might rename primitive to something else */
@@ -148,7 +147,6 @@ enum ast_node_type {
/** Macro definition. */
AST_MACRO_CONSTRUCT,
AST_MACRO_EXPAND,
- AST_TYPE_CONSTRUCT,
AST_TYPE_EXPAND,
/** Procedure definition. */
AST_PROC,
@@ -228,8 +226,7 @@ enum ast_type_kind {
AST_TYPE_PRIMITIVE,
/** Array. */
AST_TYPE_ARR,
- /** Typeof expression. */
- AST_TYPE_TYPEOF,
+ AST_TYPE_CONSTRUCT,
/** Trait. */
AST_TYPE_TRAIT,
/** Pointer to a type. */
@@ -366,6 +363,8 @@ struct trait_implemented {
struct ast_trait {
/** Name of trait. */
struct ast_node *id;
+ /** Parameters to construct concrete type from trait. */
+ struct ast_node *params;
/** Body of trait. */
struct ast_node *body;
/** List of types that implement this trait. */
@@ -401,7 +400,7 @@ struct ast_unop {
/** A call. */
struct ast_call {
/** Name to call, whatever it may be. */
- struct ast_node *id;
+ struct ast_node *expr;
/** List of arguments to call. */
struct ast_node *args;
};
@@ -427,12 +426,6 @@ struct ast_macro_expand {
struct ast_node *args;
};
-struct ast_type_construct {
- struct ast_node *id;
- struct ast_node *params;
- struct ast_node *body;
-};
-
struct ast_type_expand {
struct ast_node *id;
struct ast_node *args;
@@ -550,7 +543,7 @@ struct ast_type {
/** Type kind. */
enum ast_type_kind kind;
/**
- * Next type element in whole type. I.e. 'u32 is two elements, one
+ * Next type element in whole type. I.e. *i9 is two elements, one
* AST_TYPE_POINTER and one AST_TYPE_ID.
*/
struct ast_node *next;
@@ -565,6 +558,11 @@ struct ast_type {
} _id;
struct {
+ struct ast_node *id;
+ struct ast_node *args;
+ } _construct;
+
+ struct {
enum ast_primitive type;
} _primitive;
@@ -578,12 +576,6 @@ struct ast_type {
struct ast_node *base;
} _ptr;
- /** Typeof. */
- struct {
- /** Expression to take type of. */
- struct ast_node *expr;
- } _typeof;
-
/** Procedure. */
struct {
/** Name. */
@@ -764,7 +756,6 @@ struct ast_node {
/** Macro definition. */
struct ast_macro_construct _macro_construct;
struct ast_macro_expand _macro_expand;
- struct ast_type_construct _type_construct;
struct ast_type_expand _type_expand;
/** Procedure definition. */
struct ast_proc _proc;
@@ -831,7 +822,8 @@ struct ast_node {
};
};
-struct ast_node *gen_arr_access(struct ast_node *base, struct ast_node *idx, struct src_loc loc);
+struct ast_node *gen_arr_access(struct ast_node *base, struct ast_node *idx,
+ struct src_loc loc);
/**
* Generate binary operation node.
@@ -843,8 +835,8 @@ struct ast_node *gen_arr_access(struct ast_node *base, struct ast_node *idx, str
*/
struct ast_node *gen_binop(enum ast_binops op,
struct ast_node *left,
- struct ast_node *right,
- struct src_loc loc);
+ struct ast_node *right,
+ struct src_loc loc);
/**
* Generate unary operation.
@@ -862,7 +854,8 @@ struct ast_node *gen_unop(enum ast_unops op, struct ast_node *expr);
* @param args Arguments to call.
* @return Corresponding AST node.
*/
-struct ast_node *gen_call(struct ast_node *id, struct ast_node *args);
+struct ast_node *gen_call(struct ast_node *id, struct ast_node *args,
+ struct src_loc loc);
/**
* Generate ID.
@@ -963,21 +956,18 @@ struct ast_node *gen_ctrl(enum ast_ctrl_kind kind, struct src_loc loc);
* @param body Macro body.
* @return Corresponding AST node.
*/
-struct ast_node *gen_macro_construct(struct ast_node *id, struct ast_node *params,
- struct ast_node *body);
-
-struct ast_node *gen_macro_expand(struct ast_node *id, struct ast_node *args, struct src_loc loc);
+struct ast_node *gen_macro_construct(struct ast_node *id,
+ struct ast_node *params,
+ struct ast_node *body);
-struct ast_node *gen_type_construct(struct ast_node *id,
- struct ast_node *params,
- struct ast_node *body,
- struct src_loc loc);
+struct ast_node *gen_macro_expand(struct ast_node *id, struct ast_node *args,
+ struct src_loc loc);
/** @todo change args to type type when I figure out how it should be
* constructed */
struct ast_node *gen_type_expand(struct ast_node *id,
- struct ast_node *args,
- struct src_loc loc);
+ struct ast_node *args,
+ struct src_loc loc);
/**
* Generate if.
@@ -1018,8 +1008,9 @@ struct ast_node *gen_primitive(enum ast_primitive type, struct src_loc loc);
* @param rets Return type, when applicable.
* @return Corresponding AST node.
*/
-struct ast_node *gen_type(enum ast_type_kind kind, struct ast_node *id,
- struct ast_node *decl, struct ast_node *rets);
+struct ast_node *gen_type(enum ast_type_kind kind, struct ast_node *t2,
+ struct ast_node *t1,
+ struct src_loc loc);
/**
* Generate block.
@@ -1038,7 +1029,7 @@ struct ast_node *gen_block(struct ast_node *body);
* @return Corresponding AST node.
*/
struct ast_node *gen_var(struct ast_node *id, struct ast_node *type,
- struct ast_node *init);
+ struct ast_node *init, struct src_loc loc);
/**
* Generate lambda.
@@ -1069,7 +1060,7 @@ struct ast_node *gen_proc(struct ast_node *id, struct ast_node *type,
* @param id Name to do dot with.
* @return Corresponding AST node.
*/
-struct ast_node *gen_dot(struct ast_node *expr, struct ast_node *id);
+struct ast_node *gen_dot(struct ast_node *expr, struct ast_node *id, struct src_loc loc);
/**
* Generate enum definition.
@@ -1107,7 +1098,8 @@ struct ast_node *gen_alias(struct ast_node *id, struct ast_node *type);
* @param body Body.
* @return Corresponding AST node.
*/
-struct ast_node *gen_trait(struct ast_node *id, struct ast_node *body);
+struct ast_node *gen_trait(struct ast_node *id, struct ast_node *params,
+ struct ast_node *body, struct src_loc loc);
/**
* Generate import;
diff --git a/include/ek/ops.h b/include/ek/ops.h
index 0d9d433..a7672d7 100644
--- a/include/ek/ops.h
+++ b/include/ek/ops.h
@@ -2,6 +2,7 @@
#define EK_OPS_H
#include <ek/ast.h>
+#include <stdio.h>
enum loc_kind {
LOC_NONE, LOC_REG, LOC_MEM
@@ -10,8 +11,6 @@ enum loc_kind {
struct loc {
enum loc_kind kind;
struct loc *next;
- size_t start;
- size_t end;
size_t reg;
long long off;
size_t width;
@@ -50,10 +49,7 @@ struct ops {
struct op *head;
};
-struct ops *create_ops();
-void destroy_ops(struct ops *ops);
-int lower_ops(struct scope *root, struct ops *ops);
-int alloc_regs(struct ops *ops);
-int print_asm(struct ops *ops, const char *output);
+int lower_ops(struct scope *root, const char *fname);
+int print_asm(struct ops *ops, FILE *f);
#endif /* EK_OPS_H */
diff --git a/include/ek/scope.h b/include/ek/scope.h
index 10b0aad..9c4224e 100644
--- a/include/ek/scope.h
+++ b/include/ek/scope.h
@@ -49,83 +49,6 @@ struct actual {
struct actual *next;
};
-/**
- * Callable nodes visible to scope.
- *
- * Each callable consists of an ID and
- * a resolution tree built from parameters the
- * callable can take.
- * Parameters passed to the callable are
- * matched against this resolution tree to know
- * which callable to choose.
- */
-struct resolve {
- /** Resolve tree of resolve. */
- struct resolve_node *root;
- /** AST node ID of resolve. */
- struct ast_node *id;
- /** Next resolve node. */
- struct resolve *next;
-};
-
-/** A parameter node in the procedure resolution tree. */
-struct param_node {
- /** Parameter type. */
- struct ast_node *type;
- /** Fully resolved procedure if there is no next node. */
- struct resolve_node *resolved;
- /** Next parameter node in current parameter slot. */
- struct param_node *next;
-};
-
-/**
- * A procedure node in the resolution tree.
- *
- * A resolution tree is how Ek chooses which overloaded callable
- * to choose from. For example,
- *
- * @verbatim
- * do_stuff(u8, f32){}
- * do_stuff(u8, f64){}
- * do_stuff(u16, f32){}
- * @endverbatim
- *
- * generates a resolution tree of the form
- * @verbatim
- * callable:
- * do_stuff -> u8 -> f32
- * -> f64
- * u16 -> f32
- * @endverbatim
- *
- * When a callable is called with some arguments, the argument's types
- * are actualized and using the resolve tree, the correct do_stuff is chosen.
- *
- * Additionally, interfaces are allowed, but only as a 'fallback'. That is, if
- * no trivial parameter type matches the argument type, the fallback is checked,
- * and if the argument type doesn't implement the fallback, the resolution
- * is considered to have failed.
- *
- * Self-refential parameter types are similarly checked after primitive types.
- *
- * @note Generic structures without type arguments are considered primitive,
- * as are fully qualified generic structures, anything between is disallowed.
- * Eg.
- * @verbatim
- * struct some_struct (a A, b B) {...}
- * do_stuff(some_struct){...} // OK
- * do_stuff(some_struct(u8, u16)){} // OK
- * do_stuff(some_struct(u8)){} // ERR
- * @endverbatim
- */
-struct resolve_node {
- /** List of parameters of the current parameter slot. */
- struct param_node *params;
-
- /** Next procedure with parameter slot. */
- struct ast_node *resolved;
-};
-
struct types {
struct ast_node *id;
struct ast_node *type;
@@ -165,35 +88,12 @@ struct scope {
*/
struct actual *actuals;
- /** { types */
-
+ struct visible *vars;
+ struct visible *procs;
+ struct visible *macros;
struct visible *types;
- /** } */
-
struct visible *type_constructs;
-
- /**
- * Variables visible in scope.
- * @note Only some variables are callable, namely array variables.
- * @todo Could maybe add separate array list instead of a variable list?
- */
- struct visible *vars;
-
- struct resolve *proc_resolve;
- struct resolve *macro_resolve;
- struct resolve *type_construct_resolve;
-};
-
-/** Flags for matching objects during search. */
-enum match_flags {
- /** Search globally, not just in current scope. */
- MATCH_GLOBAL = (1 << 0),
- /**
- * Match call arguments to parameters.
- * If this flag is not present, only the name is matched.
- */
- MATCH_CALL = (1 << 1),
};
/**
@@ -236,17 +136,6 @@ void destroy_visible(struct scope *scope, struct visible *visible);
void destroy_scope(struct scope *scope);
/**
- * Create temporary scope.
- * Adds \p parent as the parent of the scope, but doesn't add the new scope
- * to the list of children \p parent has.
- * Caller is responsible for destroying the temporary scope.
- *
- * @param parent The temporary scope's parent.
- * @return New temporary scope.
- */
-struct scope *create_temp_scope(struct scope *parent);
-
-/**
* Add default stuff to scope, mainly builtin types.
*
* @param root Scope to add default stuff to.
@@ -327,7 +216,8 @@ int scope_add_var(struct scope *scope, struct ast_node *var);
* @param type Type to add to scope.
* @return \c 0 when succesful, non-zero otherwise.
*/
-int scope_add_type(struct scope *scope, struct ast_node *id, struct ast_node *type);
+int scope_add_type(struct scope *scope, struct ast_node *id,
+ struct ast_node *type);
/**
* Add procedure to scope.
@@ -359,53 +249,7 @@ int scope_add_macro(struct scope *scope, struct ast_node *macro);
*/
int scope_add_trait(struct scope *scope, struct ast_node *trait);
-int scope_add_type_construct(struct scope *scope, struct ast_node *type_construct);
-
-/**
- * Add an already allocated visible variable node to scope.
- * After initial analysis, preallocated variable nodes are actualized
- * and added back into the scope to build up the resolution tree.
- *
- * @param scope Scope to add variable node to.
- * @param var Variable to to add to scope.
- * @return \c 0 when succesful, non-zero otherwise.
- */
-int scope_add_existing_var(struct scope *scope, struct visible *var);
-
-/**
- * Add an already allocated visible procedure node to scope.
- * After initial analysis, preallocated procedure nodes are (partially)
- * actualized and added back into the scope to build up the resolution tree.
- *
- * @param scope SCope to add procedure node to.
- * @param proc Procedure to add to scope.
- * @return \c 0 when succesful, non-zero otherwise.
- */
-int scope_add_existing_proc(struct scope *scope, struct visible *proc);
-
-/**
- * Find an actualized AST node with ID in \p scope.
- * Since actuals are file global, technically no need for a file_*
- * @note Doesn't do any resolution. See scope_resolve_actual().
- *
- * @param scope Scope to look in.
- * @param id ID of actual to find.
- * @return Pointer to the actualized AST node corresponding to \p id if found,
- * otherwise \c NULL.
- */
-struct ast_node *scope_find_actual(struct scope *scope, struct ast_node *id);
-
-/**
- * Find anything with ID in \p scope.
- * @note Only looks in the current scope, so doesn't see anything outside
- * of it. See file_scope_find().
- *
- * @param scope Scope to look in.
- * @param id ID of whatever to find.
- * @return Pointer to the AST node corresponding to \p id if found,
- * otherwise \c NULL.
- */
-struct ast_node *scope_find(struct scope *scope, struct ast_node *id);
+int scope_resolve(struct scope *scope);
/**
* Find a variable with ID in \p scope.
@@ -480,16 +324,6 @@ struct ast_node *scope_find_alias(struct scope *scope, struct ast_node *id);
struct ast_node *scope_find_trait(struct scope *scope, struct ast_node *id);
/**
- * Find anything with ID visible to \p scope.
- *
- * @param scope Scope to look in.
- * @param id ID of whatever to find.
- * @return Pointer to the AST node corresponding to \p id if found,
- * otherwise \c NULL.
- */
-struct ast_node *file_scope_find(struct scope *scope, struct ast_node *id);
-
-/**
* Find a variable with ID visible to \p scope.
*
* @param scope Scope to look in.
@@ -549,110 +383,6 @@ struct ast_node *file_scope_find_alias(struct scope *scope,
* otherwise \c NULL.
*/
struct ast_node *file_scope_find_trait(struct scope *scope,
- struct ast_node *id);
-
-/**
- * Try to resolve a call to an array in \p scope.
- *
- * @param scope Scope to look in.
- * @param call AST call node to try and match to an array.
- * @return Pointer to the AST node corresponding to \p call if found,
- * otherwise \c NULL.
- */
-struct ast_node *scope_resolve_arr(struct scope *scope, struct ast_node *call);
-
-/**
- * Try to resolve a call to a macro in \p scope.
- *
- * @param scope Scope to look in.
- * @param call AST call node to try and match to a macro.
- * @return Pointer to the AST node corresponding to \p call if found,
- * otherwise \c NULL.
- */
-struct ast_node *scope_resolve_macro(struct scope *scope,
- struct ast_node *call);
-
-/**
- * Try to resolve a call to an actualized node in \p scope.
- *
- * @param scope Scope to look in.
- * @param call AST call node to try and match to an actualized node.
- * @return Pointer to the AST node corresponding to \p call if found,
- * otherwise \c NULL.
- */
-struct ast_node *scope_resolve_actual(struct scope *scope,
- struct ast_node *call);
-
-/**
- * Try to resolve a call to a procedure in \p scope.
- *
- * @param scope Scope to look in.
- * @param call AST call node to try and match to a procedure.
- * @return Pointer to the AST node corresponding to \p call if found,
- * otherwise \c NULL.
- */
-struct ast_node *scope_resolve_proc(struct scope *scope, struct ast_node *call);
-
-/**
- * Try to resolve a call to an AST node in \p scope.
- *
- * @param scope Scope to look in.
- * @param call AST call node to try and match to an AST node.
- * @return Pointer to the AST node corresponding to \p call if found,
- * otherwise \c NULL.
- */
-struct ast_node *scope_resolve_call(struct scope *scope, struct ast_node *call);
-
-/**
- * Try to resolve a call to an AST node visible to \p scope.
- *
- * @param scope Scope to look in.
- * @param call AST call node to try and match to an AST node.
- * @return Pointer to the AST node corresponding to \p call if found,
- * otherwise \c NULL.
- */
-struct ast_node *file_scope_resolve_call(struct scope *scope,
- struct ast_node *call);
-
-struct ast_node *file_scope_resolve_macro(struct scope *scope,
- struct ast_node *macro);
-
-/**
- * Check if \p arg_type implements \p param_type.
- *
- * A type implement another type if
- * a) They resolve to the same primitive type after alias and expression substitutions
- * b) One type is a trait and the other type has all members and
- * procedures specified in the trait.
- *
- * \p arg_type should never be a trait, so I suppose it's undefined if a trait
- * implements another trait.
- *
- * @param flags Flags for resolution.
- * @param scope Scope to check types in.
- * @param arg_type Argument type.
- * @param param_type Parameter type.
- * @return \c 1 if \p arg_type implements \p param_type, \c 0 otherwise.
- */
-int implements(enum match_flags flags, struct scope *scope,
- struct ast_node *arg_type,
- struct ast_node *param_type);
-
-/**
- * Check if type is primitive.
- *
- * @param type Type to check.
- * @return \c 1 if \p type is primitive, \c 0 otherwise.
- */
-int primitive_type(struct ast_node *type);
-
-/**
- * Check if type is fully qualified.
- * A fully qualified type is a struct or union with all type parameters filled.
- *
- * @param type Type to check.
- * @return \c 1 if \p type is fully qualified, \c 0 otherwise.
- */
-int fully_qualified(struct ast_node *type);
+ struct ast_node *id);
#endif /* SCOPE_H */