blob: ff6457289a3783c0520a8ea6a997592fe53f3b54 [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"
Damien George55baff42014-01-21 21:40:13 +00009#include "qstr.h"
Damien429d7192013-10-04 19:53:11 +010010#include "lexer.h"
Damien429d7192013-10-04 19:53:11 +010011#include "parse.h"
12#include "scope.h"
Damiend99b0522013-12-21 18:17:45 +000013#include "runtime0.h"
Damien429d7192013-10-04 19:53:11 +010014#include "emit.h"
15
Damien George1dc76af2014-02-26 16:57:08 +000016#define EMIT(fun, ...) (emit_method_table->fun(emit, __VA_ARGS__))
Damien429d7192013-10-04 19:53:11 +010017
Damien4b03e772013-10-05 14:17:09 +010018void emit_common_load_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr) {
19 // assumes pass is greater than 1, ie that all identifiers are defined in the scope
Damien429d7192013-10-04 19:53:11 +010020
Damien4b03e772013-10-05 14:17:09 +010021 id_info_t *id = scope_find(scope, qstr);
22 assert(id != NULL); // TODO can this ever fail?
Damien429d7192013-10-04 19:53:11 +010023
24 // call the emit backend with the correct code
Damien4b03e772013-10-05 14:17:09 +010025 if (id == NULL || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
Damien429d7192013-10-04 19:53:11 +010026 EMIT(load_name, qstr);
Damien4b03e772013-10-05 14:17:09 +010027 } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
Damien429d7192013-10-04 19:53:11 +010028 EMIT(load_global, qstr);
Damien4b03e772013-10-05 14:17:09 +010029 } else if (id->kind == ID_INFO_KIND_LOCAL) {
30 EMIT(load_fast, qstr, id->local_num);
31 } else if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
Damien27fb45e2013-10-20 15:07:49 +010032 EMIT(load_deref, qstr, id->local_num);
Damien429d7192013-10-04 19:53:11 +010033 } else {
34 assert(0);
35 }
36}
37
Damien4b03e772013-10-05 14:17:09 +010038void emit_common_store_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr) {
39 // assumes pass is greater than 1, ie that all identifiers are defined in the scope
Damien429d7192013-10-04 19:53:11 +010040
Damien4b03e772013-10-05 14:17:09 +010041 id_info_t *id = scope_find(scope, qstr);
42 assert(id != NULL); // TODO can this ever fail?
Damien429d7192013-10-04 19:53:11 +010043
44 // call the emit backend with the correct code
45 if (id == NULL || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
46 EMIT(store_name, qstr);
47 } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
48 EMIT(store_global, qstr);
49 } else if (id->kind == ID_INFO_KIND_LOCAL) {
50 EMIT(store_fast, qstr, id->local_num);
51 } else if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
Damien27fb45e2013-10-20 15:07:49 +010052 EMIT(store_deref, qstr, id->local_num);
Damien429d7192013-10-04 19:53:11 +010053 } else {
54 assert(0);
55 }
56}
57
Damien4b03e772013-10-05 14:17:09 +010058void emit_common_delete_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qstr) {
59 // assumes pass is greater than 1, ie that all identifiers are defined in the scope
60
61 id_info_t *id = scope_find(scope, qstr);
62 assert(id != NULL); // TODO can this ever fail?
Damien429d7192013-10-04 19:53:11 +010063
64 // call the emit backend with the correct code
65 if (id == NULL || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
66 EMIT(delete_name, qstr);
67 } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
68 EMIT(delete_global, qstr);
69 } else if (id->kind == ID_INFO_KIND_LOCAL) {
70 EMIT(delete_fast, qstr, id->local_num);
71 } else if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
Damien27fb45e2013-10-20 15:07:49 +010072 EMIT(delete_deref, qstr, id->local_num);
Damien429d7192013-10-04 19:53:11 +010073 } else {
74 assert(0);
75 }
76}