Giter VIP home page Giter VIP logo

ziglang / zig Goto Github PK

View Code? Open in Web Editor NEW
30.7K 30.7K 2.2K 290.17 MB

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.

Home Page: https://ziglang.org

License: MIT License

CMake 0.14% C++ 0.88% C 1.67% Shell 0.04% Zig 97.02% HTML 0.03% JavaScript 0.08% Python 0.13% Assembly 0.01% Objective-C 0.01% PowerShell 0.02%
compiler language zig

zig's People

Contributors

alexnask avatar andrewrk avatar daurnimator avatar dweiller avatar firefox317 avatar g-w1 avatar hejsil avatar ianic avatar ifreund avatar jacobly0 avatar jedisct1 avatar joachimschmidt557 avatar kcbanner avatar koachan avatar kristoff-it avatar kubkon avatar lemonboy avatar leroycep avatar luukdegram avatar marler8997 avatar mikdusan avatar mlugg avatar snektron avatar squeek502 avatar thejoshwolfe avatar tiehuis avatar topolarity avatar vexu avatar wooster0 avatar xackus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zig's Issues

error type

  • if you forget to check the error, compiler catches it
  • %T type
  • %expr to wrap expr in error type
  • %%expr prefix operator which is sugar for expr %% unreachable{}.
  • expr1 %% expr2 operator, where expr1 must be an error type. expr evaluates to unwrapped success value. expr2 must match or be unreachable. Alternate form: expr1 %% (err) => expr2.
  • %return expr evaluates expr and returns if and only if expr evaluated to an error
  • %void codegens to a single integer, same as enum with all void fields.
  • pub %.Foo; to declare an error value.
  • switch statement on an error
  • cast error to string to get string value for it
  • remove %return in favor of just the %% binary operator

audit alignment

For example, we set size_in_bits on a bool to 1. But then later when making an array type we use this value and multiply by the array size. Is that right?

On structs when making the member debug type we set the alignment of members and calculate the offset in bits to each member. Are we doing it right?

We also set the alignment for structs and have the option to set alignment on local variables and parameters, and more.

Related, figure out exactly what is the difference between packed structs and normal structs. Will LLVM re-order fields to improve alignment? Or is that our job? If LLVM does it, how do we know which values to give to the debug info? If we do it then we need to add that to codegen.

  • audit alignment of struct themselves, as well as fields within the struct
  • audit alignment of parameters to functions
  • audit alignment of local variable allocations, and of loads and stores. look at the llvm api what instructions take alignment parameters, and use clang to generate C code to make sure we're doing it correctly.
  • search the lang ref for "align" and make sure we're setting the alignment of all the instructions that take alignment as an argument

language features to add gdb support for user types

For example, if the user creates their own List struct, it would be nice if gdb knew about that and could represent it. Example: https://github.com/thejoshwolfe/legend-of-swarkland/blob/fc2947475b04f6d3de711b9040f61e79e06eda67/debug-scripts/list.py

It would be convenient if this could be integrated into zig somehow. zig could generate the .debug_gdb_scripts section: https://sourceware.org/gdb/onlinedocs/gdb/dotdebug_005fgdb_005fscripts-section.html

syntax conflict between if expression and struct value expression

if guess < answer {

}

Parser thinks answer { is a struct value expression.

Possible resolutions:

  • re-introduce ( and ) in block expressions
  • change struct value expression syntax somehow
  • require types to begin with an upper case letter and variables to begin with a lower case letter

support pointer arithmetic

  • pointer +/- number literal
  • pointer +/- integer
  • pointer - pointer
  • pointer +=, -= integer
  • pointer +=, -= number literal

implement zig string literals

Bare string literal: "example"
Type would be: [u8; 7]
No automatic null character.

Implicit automatic conversion to string type, which is essentially a type def to:

struct string {
    ptr: *const u8,
    len: usize,
}

C string literal: c"example"
Type is: *const u8
Automatic null character.

As a litmus test, if you try to pass a string to a C function, the param type would be *const u8. This would be a type mismatch. If you pass a C string literal it would work fine.

while loop

while condition {
     continue;
     break;
}
  • while loop
  • continue statement
  • break statement
  • error using continue or break outside a while loop

improved error diagnostics when unable to inline a function

Actual Behavior

test3.zig

test {
    const p = &foo;
    p();
}

inline fn foo() void {}
$ stage2/bin/zig test test3.zig
Global is external, but doesn't have external or weak linkage!
void ()* @test3.foo

Expected Behavior

Allowed, but p is comptime pointer to a comptime-known function body. If var is used instead of const then it should be "error: pointer to inline function must be comptime-known"

file not found on Ubuntu

josh@jash:~/dev/zig$ mkdir build
josh@jash:~/dev/zig$ cd build
josh@jash:~/dev/zig/build$ cmake ..
-- The CXX compiler identification is GNU 5.2.1
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
Configuring zig version 0.0.0
-- Found LLVM: -lLLVMLTO -lLLVMObjCARCOpts -lLLVMLinker -lLLVMBitWriter -lLLVMIRReader -lLLVMBPFCodeGen -lLLVMBPFDesc -lLLVMBPFInfo -lLLVMBPFAsmPrinter -lLLVMAMDGPUCodeGen -lLLVMAMDGPUAsmParser -lLLVMAMDGPUUtils -lLLVMAMDGPUDesc -lLLVMAMDGPUInfo -lLLVMAMDGPUAsmPrinter -lLLVMSystemZDisassembler -lLLVMSystemZCodeGen -lLLVMSystemZAsmParser -lLLVMSystemZDesc -lLLVMSystemZInfo -lLLVMSystemZAsmPrinter -lLLVMHexagonDisassembler -lLLVMHexagonCodeGen -lLLVMHexagonDesc -lLLVMHexagonInfo -lLLVMNVPTXCodeGen -lLLVMNVPTXDesc -lLLVMNVPTXInfo -lLLVMNVPTXAsmPrinter -lLLVMCppBackendCodeGen -lLLVMCppBackendInfo -lLLVMMSP430CodeGen -lLLVMMSP430Desc -lLLVMMSP430Info -lLLVMMSP430AsmPrinter -lLLVMXCoreDisassembler -lLLVMXCoreCodeGen -lLLVMXCoreDesc -lLLVMXCoreInfo -lLLVMXCoreAsmPrinter -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMPowerPCDisassembler -lLLVMPowerPCCodeGen -lLLVMPowerPCAsmParser -lLLVMPowerPCDesc -lLLVMPowerPCInfo -lLLVMPowerPCAsmPrinter -lLLVMSparcDisassembler -lLLVMSparcCodeGen -lLLVMSparcAsmParser -lLLVMSparcDesc -lLLVMSparcInfo -lLLVMSparcAsmPrinter -lLLVMMIRParser -lLLVMAsmParser -lLLVMLibDriver -lLLVMOption -lLLVMDebugInfoPDB -lLLVMTableGen -lLLVMOrcJIT -lLLVMLineEditor -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMDebugInfoDWARF -lLLVMPasses -lLLVMipo -lLLVMVectorize -lLLVMInterpreter -lLLVMExecutionEngine -lLLVMRuntimeDyld -lLLVMCodeGen -lLLVMTarget -lLLVMScalarOpts -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMInstCombine -lLLVMInstrumentation -lLLVMTransformUtils -lLLVMipa -lLLVMMC -lLLVMAnalysis -lLLVMCore -lLLVMSupport;-lz -lpthread -lffi -ledit -ltinfo -ldl -lm  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/josh/dev/zig/build
josh@jash:~/dev/zig/build$ make
Scanning dependencies of target run_tests
[  7%] Building CXX object CMakeFiles/run_tests.dir/src/buffer.cpp.o
[ 15%] Building CXX object CMakeFiles/run_tests.dir/src/util.cpp.o
[ 23%] Building CXX object CMakeFiles/run_tests.dir/src/os.cpp.o
[ 30%] Building CXX object CMakeFiles/run_tests.dir/test/standalone.cpp.o
Linking CXX executable run_tests
[ 30%] Built target run_tests
Scanning dependencies of target zig
[ 38%] Building CXX object CMakeFiles/zig.dir/src/buffer.cpp.o
[ 46%] Building CXX object CMakeFiles/zig.dir/src/error.cpp.o
[ 53%] Building CXX object CMakeFiles/zig.dir/src/main.cpp.o
[ 61%] Building CXX object CMakeFiles/zig.dir/src/parser.cpp.o
[ 69%] Building CXX object CMakeFiles/zig.dir/src/tokenizer.cpp.o
[ 76%] Building CXX object CMakeFiles/zig.dir/src/util.cpp.o
[ 84%] Building CXX object CMakeFiles/zig.dir/src/codegen.cpp.o
[ 92%] Building CXX object CMakeFiles/zig.dir/src/zig_llvm.cpp.o
[100%] Building CXX object CMakeFiles/zig.dir/src/os.cpp.o
Linking CXX executable zig
[100%] Built target zig
josh@jash:~/dev/zig/build$ ./zig build --output hello ../test/hello.zig 
Original source:
----------------
#link("c")
extern {
    fn puts(s: *mut u8) -> i32;
    fn exit(code: i32) -> unreachable;
}

fn _start() -> unreachable {
    puts("Hello, world!");
    exit(0);
}


Tokens:
---------
NumberSign #
Symbol link
LParen (
StringLiteral "c"
RParen )
Extern extern
LBrace {
Fn fn
Symbol puts
LParen (
Symbol s
Colon :
Star *
Mut mut
Symbol u8
RParen )
Arrow ->
Symbol i32
Semicolon ;
Fn fn
Symbol exit
LParen (
Symbol code
Colon :
Symbol i32
RParen )
Arrow ->
Unreachable unreachable
Semicolon ;
RBrace }
Fn fn
Symbol _start
LParen (
RParen )
Arrow ->
Unreachable unreachable
LBrace {
Symbol puts
LParen (
StringLiteral "Hello, world!"
RParen )
Semicolon ;
Symbol exit
LParen (
NumberLiteral 0
RParen )
Semicolon ;
RBrace }
EOF 

AST:
------
Root
  ExternBlock
    FnDecl
      FnProto 'puts'
        ParamDecl 's'
          'mut' PointerType
            Type 'u8'
        Type 'i32'
    FnDecl
      FnProto 'exit'
        ParamDecl 'code'
          Type 'i32'
        Type 'unreachable'
  FnDef
    FnProto '_start'
      Type 'unreachable'
    Block
      FnCallExpression
        FnCall 'puts'
          StringLiteralExpression 'Hello, world!'
      FnCallExpression
        FnCall 'exit'
          NumberLiteralExpression 0

Semantic Analysis:
--------------------
OK

Code Generation:
------------------
; ModuleID = 'ZigModule'

@0 = private unnamed_addr constant [14 x i8] c"Hello, world!\00"

; Function Attrs: noreturn
declare void @exit(i32) #0

declare i32 @puts(i8*)

; Function Attrs: noreturn nounwind
define void @_start() #1 {
entry:
  %0 = call i32 @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @0, i32 0, i32 0)), !dbg !8
  call void @exit(i32 0), !dbg !10
  unreachable, !dbg !10
}

attributes #0 = { noreturn }
attributes #1 = { noreturn nounwind }

!llvm.dbg.cu = !{!0}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "zig 0.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)
!1 = !DIFile(filename: "hello.zig", directory: "../test")
!2 = !{}
!3 = !{!4}
!4 = !DISubprogram(name: "_start", scope: !1, file: !1, line: 7, type: !5, isLocal: false, isDefinition: true, scopeLine: 7, isOptimized: false, function: void ()* @_start, variables: !2)
!5 = !DISubroutineType(types: !6)
!6 = !{!7}
!7 = !DIBasicType(name: "void", encoding: DW_ATE_unsigned)
!8 = !DILocation(line: 8, column: 5, scope: !9)
!9 = distinct !DILexicalBlock(scope: !4, file: !1, line: 7, column: 28)
!10 = !DILocation(line: 9, column: 5, scope: !9)

Link:
-------
OK
josh@jash:~/dev/zig/build$ ./hello 
bash: ./hello: No such file or directory

The problem is that ./hello is linked against /lib/ld64.so.1 instead of /lib64/ld-linux-x86-64.so.2. This seems to be due to ld being misconfigured on Debian.

This patch can work around the issue:

diff --git a/src/codegen.cpp b/src/codegen.cpp
index d59eff3..8318a43 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -721,6 +721,8 @@ void code_gen_link(CodeGen *g, const char *out_file) {
     if (g->is_static) {
         args.append("-static");
     }
+    args.append("-dynamic-linker");
+    args.append("/lib64/ld-linux-x86-64.so.2");
     args.append("-o");
     args.append(out_file);
     args.append((const char *)buf_ptr(&out_file_o));

import segregation

  • In /my/project/path if I import "std.zig" which is in /usr/lib/zig/lib/std.zig, and then "std.zig" wants to import its own dependencies, those should be looking in the /usr/lib/zig/lib/ root, and not searching /my/project/path.
  • If a.zig imports b.zig and then b.zig imports c.zig, a.zig should not see c.zig symbols.
  • Ability to import into a namespace in addition to importing all. `import a = "a.zig";
  • rename use to import ?

implement goto

goto has some requirements:

  • jumping into a block should be an error
  • jumping over a variable declaration, error
  • jumping over a defer statement, error
  • jumping out of scope should run the defers

support tagged unions

  • - enums where all types are void (or left unspecified) codegen to a simple unsigned integer with the smallest bit width possible.
  • - support enums with values attached
  • - implement #enum_count(...)
  • - exported enums
  • - pub enums
  • - fix debug offsets so that union values display correctly
  • instead of function invocation to create an enum value with a payload, Foo.One { Point { .x = 1, .y = 2,} }
  • comparison operators shouldn't work for enums with payloads

number literal type

Currently all number literals are i32. Instead, have a number literal type which gets implicitly casted to the other numeric types.

a + b + c expression is broken

export executable "hello";

use "std.zig";

export fn main(argc : isize, argv : *mut *mut u8, env : *mut *mut u8) -> i32 {
    print_str("Hello, world!\n", (14 + 0 + 0) as isize);
    return 0;
}
hello2.zig:6:42: error: invalid token: '+'
    print_str("Hello, world!\n", (14 + 0 + 0) as isize);
                                         ^

generics

  • make type an expression
  • make type expressions primary expressions
  • make overflow intrinsic type generic
  • merge # functions into @
  • Analyze code starting with exported things as entry points in the graph.
  • generic function
  • struct can take arguments
  • enum can take arguments
  • Make List and HashTable data structures for the standard library to see how well the generics perform.
  • member functions have generic args in context

order-independent declarations

  • using #typeof() on the declaration below
  • using #typeof() for a parameter type
  • detect #typeof() loop
  • using #typeof() on an imported symbol

We'll construct a dependency graph of every declaration with a type and then do the correct order.

switch expression

  • error when else missing for integer types
  • switch on a simple enum
  • switch on a range of chars 'a'...'z'
  • else prong
  • error when missing prongs
  • switch with enum with extra data attached
  • use * to get a pointer to the extra data attached (same as for loop)
  • switch on error type
  • when switching on an enum, prongs don't need namespace prefix
  • switch where all prong expressions are unreachable type
  • switch with no expected type and we have to resolve the prong types as peers
  • |x| expr syntax
  • no error when else missing when all integer types handled
  • error when two prongs match the same case

add sizeof

this returns the byte count of something known at compile time.

also think about getting the array length of static initialized arrays.

integer wrapping

  • add 'w' variants of integer types which means "wrapping". see code below.
  • fix codegen for non 'w' variants of integers to emit correct nuw/nsw.
  • make pointer arithmetic non wrapping
  • in debug mode, make integer overflow in arithmetic panic. in release mode, undefined behavior.
  • tests for add, sub, mul, shl, negate wrapping crashing
  • tests for add, sub, mul, shl, negate working with wrapping types
  • eval tests for add, sub, mul, shl, negate wrapping cause compile error
  • eval tests for add, sub, mul, shl, negate working with wrapping types
  • when adding normal int to wrapping int, wrapping type takes precedence
  • @shl_with_overflow builtin fn
#max_value(i32) + 1 // undefined behavior. -nuw +nsw
#max_value(u32) + 1 // undefined behavior. +nuw -nsw
#max_value(iw32) + 1 == #min_value(iw32) // -nuw -nsw
#max_value(uw32) + 1 == #min_value(uw32) // -nuw -nsw

support structs

struct Aoeu {
    field: i32,
    field2: bool,
}
  • struct on the stack, read / write fields
  • accept a struct pointer as a parameter. read / write fields
  • debug information for structs
  • struct which has a member which is a pointer to same struct
  • struct which has a member which is another struct declared later
  • circular reference struct is an error
  • invalid field access error test
  • assign to invalid field error test
  • assign one byvalue struct to another
  • struct initializer syntax
  • assign field to constant struct error
  • redefinition of struct error
  • pub vs private vs export structs
  • error for modifying a byval parameter
  • error for byval struct parameter in exported function (since we don't yet support it)
  • error for missing field in struct value expression
  • error for incorrect field in struct value expression
  • error for taking mutable address of const struct field

add function pointer support

  • put a bunch of fn pointers in an array and call one
  • fix var args fns
  • store member fn in variable
  • call member fn directly
  • member fns in an array
  • as the result of an if-else
  • add parsing support for fn types

add panic function

panic function prints a stack trace to stderr in debug mode; calls abort (after printing a message to stderr) in release mode.

Then make unreachable codegen to panic("unreachable") in debug mode, and to unreachable in release mode.

maybe type

  • generic ? syntax for declaring a maybe type
  • syntax for assigning the maybe state to a maybe type
  • if (const foo ?= expression) {} syntax
  • ?? unwrapping expression
  • test for many ? qualifiers on a type
  • optimization for bool - use 0 for false, 1 for true, 2 for maybe state
  • optimization for pointer - use null pointer for maybe state
  • error for if var expression initializer not maybe type

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.