write object file and fix void return type
parent
e112818e25
commit
c2e5d50027
|
@ -30,6 +30,7 @@ set(ZIG_SOURCES
|
|||
"${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/util.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"
|
||||
)
|
||||
|
||||
set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
|
||||
|
@ -38,10 +39,6 @@ configure_file (
|
|||
${CONFIGURE_OUT_FILE}
|
||||
)
|
||||
|
||||
# GTFO, -lstdc++ !!
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
|
||||
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-unused-variable -Wno-unused-but-set-variable")
|
||||
|
||||
set(EXE_CFLAGS "-std=c++11 -Werror -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes")
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "codegen.hpp"
|
||||
#include "hash_map.hpp"
|
||||
#include "zig_llvm.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
|
||||
struct FnTableEntry {
|
||||
LLVMValueRef fn_value;
|
||||
AstNode *proto_node;
|
||||
|
@ -49,6 +54,7 @@ static void add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
|
|||
static LLVMTypeRef to_llvm_type(AstNode *type_node) {
|
||||
assert(type_node->type == NodeTypeType);
|
||||
assert(type_node->codegen_node);
|
||||
assert(type_node->codegen_node->data.type_ref);
|
||||
|
||||
return type_node->codegen_node->data.type_ref;
|
||||
}
|
||||
|
@ -134,9 +140,12 @@ static void analyze_node(CodeGen *g, AstNode *node) {
|
|||
node->codegen_node->data.type_ref = LLVMInt8Type();
|
||||
} else if (buf_eql_str(name, "i32")) {
|
||||
node->codegen_node->data.type_ref = LLVMInt32Type();
|
||||
} else if (buf_eql_str(name, "void")) {
|
||||
node->codegen_node->data.type_ref = LLVMVoidType();
|
||||
} else {
|
||||
add_node_error(g, node,
|
||||
buf_sprintf("invalid type name: '%s'", buf_ptr(name)));
|
||||
node->codegen_node->data.type_ref = LLVMInt8Type();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -339,3 +348,42 @@ void code_gen(CodeGen *g) {
|
|||
ZigList<ErrorMsg> *codegen_error_messages(CodeGen *g) {
|
||||
return &g->errors;
|
||||
}
|
||||
|
||||
|
||||
void code_gen_link(CodeGen *g, bool is_static, const char *out_file) {
|
||||
LLVMInitializeAllTargets();
|
||||
LLVMInitializeAllTargetMCs();
|
||||
LLVMInitializeAllAsmPrinters();
|
||||
LLVMInitializeAllAsmParsers();
|
||||
LLVMInitializeNativeTarget();
|
||||
|
||||
|
||||
LLVMPassRegistryRef registry = LLVMGetGlobalPassRegistry();
|
||||
LLVMInitializeCore(registry);
|
||||
LLVMInitializeCodeGen(registry);
|
||||
LLVMZigInitializeLoopStrengthReducePass(registry);
|
||||
LLVMZigInitializeLowerIntrinsicsPass(registry);
|
||||
LLVMZigInitializeUnreachableBlockElimPass(registry);
|
||||
|
||||
char *native_triple = LLVMGetDefaultTargetTriple();
|
||||
|
||||
LLVMTargetRef target_ref;
|
||||
char *err_msg = nullptr;
|
||||
if (LLVMGetTargetFromTriple(native_triple, &target_ref, &err_msg)) {
|
||||
zig_panic("unable to get target from triple: %s", err_msg);
|
||||
}
|
||||
|
||||
char *native_cpu = LLVMZigGetHostCPUName();
|
||||
char *native_features = LLVMZigGetNativeFeatures();
|
||||
|
||||
LLVMCodeGenOptLevel opt_level = LLVMCodeGenLevelNone;
|
||||
|
||||
LLVMRelocMode reloc_mode = is_static ? LLVMRelocStatic : LLVMRelocPIC;
|
||||
|
||||
LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(target_ref, native_triple,
|
||||
native_cpu, native_features, opt_level, reloc_mode, LLVMCodeModelDefault);
|
||||
|
||||
if (LLVMTargetMachineEmitToFile(target_machine, g->mod, strdup(out_file), LLVMObjectFile, &err_msg)) {
|
||||
zig_panic("unable to write object file: %s", err_msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_CODEGEN_HPP
|
||||
#define ZIG_CODEGEN_HPP
|
||||
|
||||
|
@ -20,6 +27,8 @@ void semantic_analyze(CodeGen *g);
|
|||
|
||||
void code_gen(CodeGen *g);
|
||||
|
||||
void code_gen_link(CodeGen *g, bool is_static, const char *out_file);
|
||||
|
||||
ZigList<ErrorMsg> *codegen_error_messages(CodeGen *g);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_HASH_MAP_HPP
|
||||
#define ZIG_HASH_MAP_HPP
|
||||
|
||||
|
|
|
@ -112,6 +112,10 @@ static int build(const char *arg0, const char *in_file, const char *out_file, Zi
|
|||
fprintf(stderr, "------------------\n");
|
||||
code_gen(codegen);
|
||||
|
||||
fprintf(stderr, "\nLink:\n");
|
||||
fprintf(stderr, "------------------\n");
|
||||
code_gen_link(codegen, false, out_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "parser.hpp"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -168,6 +175,13 @@ static AstNode *ast_create_node_with_node(NodeType type, AstNode *other_node) {
|
|||
return node;
|
||||
}
|
||||
|
||||
static AstNode *ast_create_void_type_node(ParseContext *pc, Token *token) {
|
||||
AstNode *node = ast_create_node(NodeTypeType, token);
|
||||
node->data.type.type = AstNodeTypeTypePrimitive;
|
||||
buf_init_from_str(&node->data.type.primitive_name, "void");
|
||||
return node;
|
||||
}
|
||||
|
||||
static void ast_buf_from_token(ParseContext *pc, Token *token, Buf *buf) {
|
||||
buf_init_from_mem(buf, buf_ptr(pc->buf) + token->start_pos, token->end_pos - token->start_pos);
|
||||
}
|
||||
|
@ -468,13 +482,11 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, int token_index, int *new_t
|
|||
ast_parse_param_decl_list(pc, token_index, &token_index, &node->data.fn_proto.params);
|
||||
|
||||
Token *arrow = &pc->tokens->at(token_index);
|
||||
token_index += 1;
|
||||
if (arrow->id == TokenIdArrow) {
|
||||
token_index += 1;
|
||||
node->data.fn_proto.return_type = ast_parse_type(pc, token_index, &token_index);
|
||||
} else if (arrow->id == TokenIdLBrace) {
|
||||
node->data.fn_proto.return_type = nullptr;
|
||||
} else {
|
||||
ast_invalid_token_error(pc, arrow);
|
||||
node->data.fn_proto.return_type = ast_create_void_type_node(pc, arrow);
|
||||
}
|
||||
|
||||
*new_token_index = token_index;
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_PARSER_HPP
|
||||
#define ZIG_PARSER_HPP
|
||||
|
||||
|
|
|
@ -170,6 +170,7 @@ ZigList<Token> *tokenize(Buf *buf, Buf *cur_dir_path) {
|
|||
case WHITESPACE:
|
||||
break;
|
||||
case ALPHA:
|
||||
case '_':
|
||||
t.state = TokenizeStateSymbol;
|
||||
begin_token(&t, TokenIdSymbol);
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "zig_llvm.hpp"
|
||||
|
||||
#include <llvm/InitializePasses.h>
|
||||
#include <llvm/PassRegistry.h>
|
||||
#include <llvm/MC/SubtargetFeature.h>
|
||||
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
|
||||
initializeLoopStrengthReducePass(*unwrap(R));
|
||||
}
|
||||
|
||||
void LLVMZigInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R) {
|
||||
initializeLowerIntrinsicsPass(*unwrap(R));
|
||||
}
|
||||
|
||||
void LLVMZigInitializeUnreachableBlockElimPass(LLVMPassRegistryRef R) {
|
||||
initializeUnreachableBlockElimPass(*unwrap(R));
|
||||
}
|
||||
|
||||
char *LLVMZigGetHostCPUName(void) {
|
||||
std::string str = sys::getHostCPUName();
|
||||
return strdup(str.c_str());
|
||||
}
|
||||
|
||||
char *LLVMZigGetNativeFeatures(void) {
|
||||
return strdup("");
|
||||
//SubtargetFeatures features;
|
||||
|
||||
//StringMap<bool> host_features;
|
||||
//if (sys::getHostCPUFeatures(host_features)) {
|
||||
// for (auto &F : host_features)
|
||||
// features.AddFeature(F.first(), F.second);
|
||||
//}
|
||||
|
||||
//return strdup(features.getString().c_str());
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Andrew Kelley
|
||||
*
|
||||
* This file is part of zig, which is MIT licensed.
|
||||
* See http://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#ifndef ZIG_ZIG_LLVM_HPP
|
||||
#define ZIG_ZIG_LLVM_HPP
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Target.h>
|
||||
#include <llvm-c/Initialization.h>
|
||||
#include <llvm-c/TargetMachine.h>
|
||||
|
||||
void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R);
|
||||
void LLVMZigInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
|
||||
void LLVMZigInitializeUnreachableBlockElimPass(LLVMPassRegistryRef R);
|
||||
|
||||
char *LLVMZigGetHostCPUName(void);
|
||||
char *LLVMZigGetNativeFeatures(void);
|
||||
|
||||
#endif
|
|
@ -1,8 +1,9 @@
|
|||
extern {
|
||||
fn puts(s: *mut u8) -> i32;
|
||||
fn exit(code: i32);
|
||||
}
|
||||
|
||||
fn main(argc: i32, argv: *mut *mut u8) -> i32 {
|
||||
puts("Hello, world!\n");
|
||||
return 0;
|
||||
fn _start() {
|
||||
puts("Hello, world!");
|
||||
exit(0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue