blob: e30cad74963843a0d48cbc6df5dfc3868dc10a2d [file] [log] [blame]
Damien429d7192013-10-04 19:53:11 +01001#include <unistd.h>
2#include <stdio.h>
3#include <stdint.h>
4#include <string.h>
5#include <assert.h>
6
7#include "misc.h"
Damiend99b0522013-12-21 18:17:45 +00008#include "mpconfig.h"
Damien429d7192013-10-04 19:53:11 +01009#include "lexer.h"
Damien429d7192013-10-04 19:53:11 +010010#include "parse.h"
11#include "scope.h"
Damiend99b0522013-12-21 18:17:45 +000012#include "runtime0.h"
Damien429d7192013-10-04 19:53:11 +010013#include "emit.h"
14
Damien415eb6f2013-10-05 12:19:06 +010015#define EMIT(fun, arg...) (emit_method_table->fun(emit, ##arg))
Damien429d7192013-10-04 19:53:11 +010016
Damien4b03e772013-10-05 14:17:09 +010017void emit_common_load_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr) {
18 // assumes pass is greater than 1, ie that all identifiers are defined in the scope
Damien429d7192013-10-04 19:53:11 +010019
Damien4b03e772013-10-05 14:17:09 +010020 id_info_t *id = scope_find(scope, qstr);
21 assert(id != NULL); // TODO can this ever fail?
Damien429d7192013-10-04 19:53:11 +010022
23 // call the emit backend with the correct code
Damien4b03e772013-10-05 14:17:09 +010024 if (id == NULL || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
Damien429d7192013-10-04 19:53:11 +010025 EMIT(load_name, qstr);
Damien4b03e772013-10-05 14:17:09 +010026 } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
Damien429d7192013-10-04 19:53:11 +010027 EMIT(load_global, qstr);
Damien4b03e772013-10-05 14:17:09 +010028 } else if (id->kind == ID_INFO_KIND_LOCAL) {
29 EMIT(load_fast, qstr, id->local_num);
30 } else if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
Damien27fb45e2013-10-20 15:07:49 +010031 EMIT(load_deref, qstr, id->local_num);
Damien429d7192013-10-04 19:53:11 +010032 } else {
33 assert(0);
34 }
35}
36
Damien4b03e772013-10-05 14:17:09 +010037void emit_common_store_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr) {
38 // assumes pass is greater than 1, ie that all identifiers are defined in the scope
Damien429d7192013-10-04 19:53:11 +010039
Damien4b03e772013-10-05 14:17:09 +010040 id_info_t *id = scope_find(scope, qstr);
41 assert(id != NULL); // TODO can this ever fail?
Damien429d7192013-10-04 19:53:11 +010042
43 // call the emit backend with the correct code
44 if (id == NULL || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
45 EMIT(store_name, qstr);
46 } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
47 EMIT(store_global, qstr);
48 } else if (id->kind == ID_INFO_KIND_LOCAL) {
49 EMIT(store_fast, qstr, id->local_num);
50 } else if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
Damien27fb45e2013-10-20 15:07:49 +010051 EMIT(store_deref, qstr, id->local_num);
Damien429d7192013-10-04 19:53:11 +010052 } else {
53 assert(0);
54 }
55}
56
Damien4b03e772013-10-05 14:17:09 +010057void emit_common_delete_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr) {
58 // assumes pass is greater than 1, ie that all identifiers are defined in the scope
59
60 id_info_t *id = scope_find(scope, qstr);
61 assert(id != NULL); // TODO can this ever fail?
Damien429d7192013-10-04 19:53:11 +010062
63 // call the emit backend with the correct code
64 if (id == NULL || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
65 EMIT(delete_name, qstr);
66 } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
67 EMIT(delete_global, qstr);
68 } else if (id->kind == ID_INFO_KIND_LOCAL) {
69 EMIT(delete_fast, qstr, id->local_num);
70 } else if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
Damien27fb45e2013-10-20 15:07:49 +010071 EMIT(delete_deref, qstr, id->local_num);
Damien429d7192013-10-04 19:53:11 +010072 } else {
73 assert(0);
74 }
75}