AdeptLanguage / Adept

The Adept Programming Language
GNU General Public License v3.0
122 stars 9 forks source link

Few questions. #4

Open ghost opened 4 years ago

ghost commented 4 years ago

@IsaacShelton

  1. When you'll release documentation for Adept? (I really want to learn Adept.)

  2. Is there any way to read command-line arguments like in C?

int main(int argc, char *argv[]) { ... }
ghost commented 4 years ago

@IsaacShelton Where the program for detecting this warnings and errors in binaries placed in the Adept source code? (I just want to understand how it works)

IsaacShelton commented 4 years ago

@t0md3an It's built into the same executable, adept. They're scattered throughout the codebase, because they get triggered by a variety things. Most of them are calls to compiler_warn or compiler_warnf (defined in src/DRVR/compiler.c), and a few are to yellowprintf (defined in include/UTIL/color.h).

ghost commented 4 years ago

@IsaacShelton How this is works:

I can’t find I code vsprintf() function, I just want to understand how this detector works:

$ ./file
WARNING: vsprintf(*String, String, VariadicArray) expected *ubyte value for %s, got 'int' instead
zsh: segmentation fault  ./file
ghost commented 4 years ago

Ah, I understood, this is a 2.4/parse.adept showing this warning.

ghost commented 4 years ago

@IsaacShelton Is #place/print_warning stopping program execution? If not, I think user will’ll not want to saw this warnings at every binary execution. I think will be better to move all warnings on the compilation step, not at the program execution (like in gcc).

IsaacShelton commented 4 years ago

@t0md3an #place/print_warning are done at compile time and don't stop program compilation, they also don't stop program execution because they don't exist at runtime.

The warning(s) printed at runtime shouldn't be seen at every binary execution, because warnings like the ones from 2.4/parse.adept only show up if the programmer made a mistake.

I think having compile-time warnings for printf would be a good thing, the one problem though is that the compiler can only warn you if the format string is constant. If it isn't constant, then it is impossible for the compiler to know, like in this example:

import basics

func main {
    format String = scan("Enter a string with %S in it: ")
    printf(format, "apples")
}

It is impossible to know whether printf will crash. And because of this, it is nice to have runtime warnings.

I might add compile-time checking for printf functions (when its available) or something to help prevent against users actually seeing these warnings during runtime. As of now though, you can disable the runtime warnings from printf with this:

#set vsprintf_type_checks false

Then the program will crash silently

ghost commented 4 years ago

@IsaacShelton

Yes, it works, thank you.

Have you planned to add these warnings?:

Declared but not used

\<function> should return \<type>

And some warnings from GNU C compiler

Also I think that the #print/place_error should abort compilation.

IsaacShelton commented 4 years ago

@t0md3an 1.

  1. I actually disagree with having #print/place_error abort compilation, because sometimes you want to have more information about the error after the initial error message.
    #print_error "This file requires XYZ"
    #print "(You can obtain XYZ from https://xyz.xyz/xyz.zip)"
    #halt

    However, maybe something like #error could exist and be equivalent to #print_error #halt so you get the best of both worlds

    #error "This file requires XYZ"
ghost commented 4 years ago

@IsaacShelton Is there any __asm__() in Adept like in C for calling assembler?

IsaacShelton commented 4 years ago

@t0md3an No and I don't really plan on adding one, because it's unnecessary for most programming. I don't think the benefit of adding one is worth the cost of maintaining it.

When it is necessary, Adept supports linking against C libraries, so all assembly can be written inside C and then linked against or can be exposed with C name mangling inside a plain .o file

ghost commented 4 years ago

@IsaacShelton Is there any way to compile Adept source code for Windows and Linux from MacOS (cross-compilation)?

IsaacShelton commented 4 years ago

@t0md3an Not really no, at least not easily. I'll look into it to see how hard it would be.

UPDATE: It turned out to be pretty easy for Windows. I got cross-compiling to work for targeting Windows on MacOS. I've tested it using different parts of the standard library, including OpenGL/GLFW components, and it seems to work really well. I'm pretty sure that if it can handle what I threw at it, then it can cross-compile just about anything.

The once downside though is that cross-compilation support only comes as an extension.

https://github.com/IsaacShelton/AdeptCrossCompilation/releases/

It's really easy to use though and I'm glad you asked about cross-compilation, because it seems to work great. All you gotta do is adept --windows and you have a working Windows program.

ghost commented 4 years ago

@IsaacShelton

Yes, It works well, this is a good feature for developing cross-platform apps!

1. Also I have a question about building Adept (Makefile) from MacOS for Windows and Linux. Is it possible, or I should use Windows to build Adept for Windows?

2. What utilities requires Adept compiler on Windows, Linux, MacOS?

IsaacShelton commented 4 years ago

@t0md3an

  1. It's possible to compile the Adept compiler for Windows while on MacOS. You need to install mingw-w64 with brew install mingw-w64. Then build llvm either 7 or 10 it shouldn't matter, you have to use CC as x86_64-w64-mingw32-gcc and CXX as x86_64-w64-mingw32-g++ also make sure the llvm build is using mingw32-w64 utils to build it. And then once you have llvm, you can build the compiler, and if the linker fails you'll have to replace LLVM_LIBS under the if(Windows_NT) branch.

  2. It requires llvm 7 or llvm 10, and optionally libcurl.

ghost commented 4 years ago

@IsaacShelton About n2, I mean what compiler requires after build (ld, gcc, opt etc.)

IsaacShelton commented 4 years ago

@t0md3an It requires ld and a few object files from the mingw64 project and an archive called lipdep.a which I made that contains other necessary object files. The only place to get them easily right now is by either getting ld from mingw64 and .o and libdep.a from the cross compilation extension or you can get the necessary files by installing Adept 2.3 from the Windows installer and going to C:\Adept\2.3\ and copying the .o files, libdep.a, and ld.exe and putting them with your 2.4 build of Adept. Maybe I'll add an entry in the 2.3 releases that contain the necessary files

UPDATE: All of the required files for Adept to run on Windows are now available in a conveniently compressed zip file named Adept-Windows-From-Source-Necessities.zip under releases.

On Linux, the only runtime requirement is gcc

ghost commented 4 years ago

@IsaacShelton linker warning:

adept main.adept

ld: warning: object file (main.o) was built for newer OSX version (10.15) than being linked (10.13)

How to fix this?

IsaacShelton commented 4 years ago

@t0md3an This is fixed now in the latest release

ghost commented 4 years ago

@IsaacShelton

1. For what gcc is needed in Adept?

2. How this code looks in Adept?

#include <iostream>

int main()
{
    int arr[100];
    int n; cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> arr[1];
    }
    cout << arr[1] << endl;
}
IsaacShelton commented 4 years ago

@t0md3an

  1. gcc is needed on MacOS and Linux in order for Adept to link the generated object file with additional system objects files and archives to create an executable.

  2. Something like

    
    import basics

func main { arr 100 int n int

scan(&n)
repeat n {
    scan(&arr[idx])
}
print(arr[1])

}

ghost commented 4 years ago

@IsaacShelton Your code returns this error:

terminal.adept:114:12: Undeclared function 'scanInto'!
114|    return scanInto("", result)
               ^^^^^^^^
IsaacShelton commented 4 years ago

@t0md3an This has been fixed now in AdeptImport

ghost commented 4 years ago

@IsaacShelton

1. For what uses funcptr keyword and function-pointer type?

2. Why you removed stdio's tmpnam from cstdio?

IsaacShelton commented 4 years ago

@t0md3an

  1. funcptr is a left over keyword from Adept 1.1 that isn't used anymore. It has been replaced with func & in Adept 2.x. The function-pointer type is a special kind of pointer which can point to functions. Using function pointers, you can call functions based on which function the pointer is pointing to. Function pointers are declared like this:

    my_calculate_function func(int, int) int

    They can be set to point at functions using func &

    my_calculate_function = func &sum(int, int)

    And then called like a normal function

    result int = my_calculate_function(10, 11)

    In this example, the function sum would be called with the values of 10 and 11 because the function pointer my_calculate_function points to the function sum.

  2. I removed tmpnam because it causes link-time warnings on linux. If you still want to call it, you can force defining it with:

    #define sys_cstdio_define_tmpnam true
ghost commented 4 years ago

@IsaacShelton Have you planned to add for (;;) { ... } loop to Adept and strdup() to cstring?

IsaacShelton commented 4 years ago
  1. Yes, I've planned on adding it for a long time. I haven't really needed it though, for 90% of cases, you can just use the repeat n loop instead which is equivalent to for(size_t idx = 0; idx < n; idx++) { ... }.
import basics

func main {
    scan("Enter a value for n:", def n int)
    repeat n {
        printf("n = %d\n", idx)
    }
}
  1. Yes I've added it now
ghost commented 4 years ago

@IsaacShelton Is it possible to add support for this?

if (1)
{
}

for (;;)
{
}

... other keywords that uses `{}`

If I am trying to use this syntax:

Expected '{' or ',' after conditional expression

NOTE: C allows this syntax

IsaacShelton commented 4 years ago

@t0md3an Yes this is now allowed

ghost commented 4 years ago

@IsaacShelton Have you planned to add something like try catch?

IsaacShelton commented 4 years ago

@t0md3an No, I don't plan on adding something like try catch.

Some other things that I've thought about adding to address the same problems are:

As of now, you still have to do something like this, which is kind of ugly:

func getName(out name *String) successful {
    if random(10) < 5, return false

    *name = "John"
    return true
}
ghost commented 4 years ago

@IsaacShelton

1. What is idx? Is this is default index value?

2. Have you planned to add python like for syntax to Adept? I mean two syntaxes:

for (i int; i < n; i++)

for (i in n)
IsaacShelton commented 4 years ago

@t0md3an

  1. idx is like the variable i, except the language iteself also modifies/accesses the value. It is a variable declared by the compiler when using certain loop types, like repeat and each-in, and represents the current index. It is also mutable.
import basics

func main {
    my_list <int> List
    my_list.add(31)
    my_list.add(643)
    my_list.add(23)

    each my_integer int in my_list {
        printf("my_list[%d] = %d\n", idx, my_integer)
    }
}
my_list[0] = 31
my_list[1] = 643
my_list[2] = 23

idx is similar to another automatically declared variable called it, which is the default variable name for the element variable when using each-in loops.

import basics

func main {
    my_list <int> List
    my_list.add(31)
    my_list.add(643)
    my_list.add(23)

    // No variable name specified
    //  \/
    each int in my_list {
        // Since we didn't specify a variable name for the current element, the default name of 'it' is used
        printf("my_list[%d] = %d\n", idx, it)
    }
}
my_list[0] = 31
my_list[1] = 643
my_list[2] = 23
  1. Yeah for traditional C-style for-loops we already have that:
    for i int = 0; i < 10; i++ { /* ... */ }
    for(i int = 0; i < 10; i++){ /* ... */ }
    for i int = 0; i < 10; i++, /* ... */
    for(i int = 0; i < 10; i++), /* ... */ 

and for python-style for-in loops, we already have the each-in loop:

import basics

func main {
    my_list <int> List
    my_list.add(1)
    my_list.add(2)
    my_list.add(3)

    each my_value int in my_list {
        print(my_value)
    }
}

and for python for-in-range loops, we have something similar called repeat, except the starting index is always 0.

import basics

func main {
    repeat 4 {
        printf("%d\n", idx)
    }
}
0
1
2
3
ghost commented 4 years ago

@IsaacShelton Also have you planned to add union/extern/typedef keywords and extern "C" functionality?

IsaacShelton commented 4 years ago

@t0md3an Yes. We already have extern / extern "C" in the form of the external and foreign keywords. external is used for global variables, and foreign is used for functions. They both use C name-mangling conventions and non-private linking. For example, errno is declared as:

external thread_local errno int

And printf(*ubyte, ...) is declared as:

foreign printf(*ubyte, ...) int

We also already have typedef in the form of alias. For example:

alias GLsizei = int
alias GLboolean = bool
alias GLbyte = byte
alias GLubyte = ubyte
alias GLshort = short
alias GLushort = ushort
alias GLint = int
alias GLuint = uint
alias GLfloat = float
alias GLclampf = float
alias GLdouble = double
alias GLclampd = double
alias GLenum = uint
alias GLbitfield = uint
// ...

What we don't have yet is union, which I've thought about adding but haven't really had a need for yet. Maybe I'll add it sometime soon, It shouldn't be that hard to do.

ghost commented 4 years ago

@IsaacShelton How to create a custom data type in Adept? (I mean something like time_t) In C for this can be used typedef or struct.

IsaacShelton commented 4 years ago

@t0md3an You can create custom data types by either using alias or struct. To start off, aliases are of course just alternative names for a different type. For example:

alias time_t = long
alias CString = *ubyte

Types declared with alias are treated the same as the type they are declared as (so long and time_t would be interchangeable in the previous example). For creating structure types, you can create them using struct and specifying a list of fields.

struct Person (name String, age int)

struct Book (
    title String,
    author String,
    subject String,
    id int
)

which is the same as the C code:

typedef struct {
    /* ... */
} Person;

Also in Adept, if multiple fields in a row have the same type, you only have to specify the type once, for example:

struct Book (
    title String,
    author String,
    subject String,
    id int
)

// is the same as

struct Book (title, author, subject String, id int)

You can use these user-defined types like you would any other types:

import basics

struct Person (firstname, lastname String)

func main {
    person Person
    scan("Enter your firstname: ", &person.firstname)
    scan("Enter your lastname: ", &person.lastname)
    printf("Hello there %S %S!\n", person.firstname, person.lastname)
}
ghost commented 4 years ago

@IsaacShelton

1. I think it will be good if Adept'll allow this:

someFunc int = func (num int) {
    return num + num
}

func main() 
{
    print(someFunc(1)) // 2
}

2. Please, write a table like this for all Adept data types (this is for more understanding Adept data types):

name designation
int %i
IsaacShelton commented 4 years ago

@t0md3an

  1. I'm not completely sure whether adding syntax like that would be good or not. If I ever end up doing something like that, it would probably use syntax like:
    
    Vector3f :: struct (x, y, z float)

someFunc :: func (num int) int { return num + num }

main :: func { print(someFunc(1)) }

But right now I'm not completely sold on the idea.. Sometimes I like the `::` syntax a little better, but other times I don't. As of now, I'm not going to plan on adding alternative syntax for that, because I would want to retain the ability to use the current syntax for backwards-compatibility, and then it would fracture the language into two subsets that would make learning Adept harder. And if/when you mix the two syntaxes, you get the worst of both worlds:

struct Vector3f (x, y, z float) Person :: struct (firstname, lastname String)

someFunc :: func (num int) int { return num + num }

func main { print(someFunc(1)) }


2. I'm still working on specifiers for some types, but as of now this is the table:

| name | designation |
|----|----|
| `bool` | `%B` for `true`/`false`, `%y` for `yes`/`no`, `%Y` for `Yes`/`No`|
| `byte` | doesn't have one yet, so use `%d` |
| `ubyte` | doesn't have one yet, so use `%d` or `%u` |
| `short` | doesn't have one yet, so use `%d` |
| `ushort` | doesn't have one yet, so use `%d` or `%u` |
| `int` | `%d` |
| `uint` | `%u` |
| `long` | `%l` |
| `ulong` | doesn't have one yet, so use `%u` |
| `usize` | doesn't have one yet, so use `%u` |
| `float` | doesn't have one yet, so use `%f` |
| `double` | `%f` |
| `*ubyte` | `%s` |
| `String` | `%S` |
| `ptr`/`*WhateverType` | `%p` |

I'm planning on completing these specifiers to be something like:
| name | designation |
|----|----|
| `bool` | `%b` or `%B` for `true`/`false`, `%y` for `yes`/`no`, `%Y` for `Yes`/`No`|
| `byte` | `%hhd` or `%hhi`|
| `ubyte` | `%hhu` for numeric value, `%c` for character value |
| `short` | `%hd` or `%hi` |
| `ushort` | `%hu` |
| `int` | `%d` or `%i` |
| `uint` | `%u` |
| `long` | `%ld` or `%li` or `%lld` or `%lli` |
| `ulong` | `%lu` or `%llu` |
| `usize` | `%zu` |
| `float` | `%hf` |
| `double` | `%f` |
| `*ubyte` | `%s` |
| `String` | `%S` |
| `ptr`/`*WhateverType` | `%p` |
ghost commented 4 years ago

@IsaacShelton Yes, I think :: is better, I think you should add it (just for pro programmers). I like this ::, it's beautiful.

You can also add : for variables to do something like this:

main :: func() : int {
    num : int = 0
    return 0
}

This variable definition is more logical than just num int (I have been confused about this more than once, I mean that I was confused about where is the variable and where is the type, but the num : int shows that num is : int). I think it's more understandable.

And for enum, union and struct:

Person :: struct ()
Fruit :: enum ()
Some :: union ()

I think this is more logical and more understandable.

IsaacShelton commented 4 years ago

@t0md3an I'm not gonna make it a standard part of the language until I'm certain it's a good thing, but I've added an experimental version to see how it fares since you think it could be a good thing. You can pull it down and test it out


pragma enable_experimental_colon_colon_syntax
pragma enable_experimental_colon_before_type_syntax

import basics

Person :: struct (firstname, lastname String)

main :: func {
    person: Person
    scan("Enter your name: ", &person.firstname)
    myPrintf("Hello %S!", person.firstname)
}

myPrintf :: func (format String, arguments ...) : int {
    name: String = "Hello"
    vsprintf(def result String, format, arguments)
    print(result)
    return 0
}

You need to have the following pragma directives to enable it:

pragma enable_experimental_colon_colon_syntax
pragma enable_experimental_colon_before_type_syntax

I reserve the right to remove this at any point in the future, so just be prepared for if I decide to remove it

IsaacShelton commented 4 years ago

One idea would be to allow the programmer to customize the language's syntax to a limited degree, I think that could be a good compromise. Everyone gets to use the syntax they like best, and the language isn't so rigid syntax-wise. I don't know if I'll actually do that, but it's something I'm considering. All standard library code would be written in the whatever the default syntax is, and if the user wants to use different syntax for their funcs/structs/enums/unions/whatever that's their decision. Again this is just an idea, I may or may not choose to do this

Update: After playing with the : before types syntax, I personally don't like it. Not planning to make it the standard.

Regarding the :: syntax, I kinda like it, still has the issues I mentioned a few messages ago though. For now I plan to keep it as an experimental syntax until I decide whether or not I want to officially support it

ghost commented 4 years ago

@IsaacShelton I have an idea for defining variables, you can do something like this:

// one of these:
num = 0 : int // I think it's better
num = 0 -> int
num = 0 int

because the beginner can get confused by the default entry:

num int = 0

beginner can think that int = 0, not num = 0.

But this is just an idea.

IsaacShelton commented 4 years ago

@t0md3an I've thought about different ways of doing syntax around types, and every one of them has advantages and disadvantages.

With the num : int = 0 syntax:

With the num = 0 : int, num = 0 -> int syntax:

With the num = 0 int syntax:

With the num int = 0 syntax:

From my analysis on the different ways of doing it, I still believe that num int = 0 is the best way. And num : int = 0 comes in at second place. The tradeoff between the two is speed of typing and looks versus clarity for beginners. I think that since Adept isn't intended for beginners, and is intended primarily for only a few people, the benefits of num int are worth the tradeoff. Plus, when you're using syntax highlighting or user-defined types, the issue of confusion goes away for the most part. And for the few times that confusion could take for beginners, it's set up in such a way that most people could understand that type type/variable name are reversed. And for the programmers who know what they're doing with Adept, it quickly becomes something that they're used to.

On another note, I've been considering :: syntax to become official maybe in Adept 2.5 if I still like it by the time. I like the way it looks and it feels more robust. It also matches the way Adept does variables, with the name coming before the definition, which I think brings more consistency to the language and it makes it easy to glance through functions/methods. Of course the old syntax of func functionName() void would still be supported for backwards-compatibility with versions 2.0-2.4.

With the amount of work I've been doing on Adept lately, I could decide to release Adept 2.4 sometime in the next few months. Then the transition would take place at the beginning of Adept 2.5 for having :: become the standard syntax.

ghost commented 4 years ago

@IsaacShelton What is ubyte (*ubyte, **ubyte)?

IsaacShelton commented 4 years ago

@t0md3an ubyte in an unsigned 8-bit integer. It takes up one byte of space (sizeof ubyte == 1) and can represent values from 0-255. Just like char in C, it's used as the type to hold an ascii character, but unlike in C, it is guaranteed to be unsigned.

*ubyte is pointer to a location in memory where one or more ubytes are stored. **ubyte is pointer to a pointer to a location in memory where one or more ubytes are stored.

Here's a graphic explaining it better, if you have some experience with C then its basically the same thing ubyte_pubyte_ppubyte

Just like in C where []/* are interchangable, pointers to values in memory don't indicate how many of what they point to is there. So **ubyte could be a pointer to a C-String, or it could be a location in memory where several C-Strings are stored.

Hopefully this explanation helps

ghost commented 4 years ago

@t0md3an

  1. I'm not completely sure whether adding syntax like that would be good or not. If I ever end up doing something like that, it would probably use syntax like:
Vector3f :: struct (x, y, z float)

someFunc :: func (num int) int {
    return num + num
}

main :: func {
    print(someFunc(1))
}

But right now I'm not completely sold on the idea.. Sometimes I like the :: syntax a little better, but other times I don't. As of now, I'm not going to plan on adding alternative syntax for that, because I would want to retain the ability to use the current syntax for backwards-compatibility, and then it would fracture the language into two subsets that would make learning Adept harder. And if/when you mix the two syntaxes, you get the worst of both worlds:

struct Vector3f (x, y, z float)
Person :: struct (firstname, lastname String)

someFunc :: func (num int) int {
    return num + num
}

func main {
    print(someFunc(1))
}
  1. I'm still working on specifiers for some types, but as of now this is the table:

name designation bool %B for true/false, %y for yes/no, %Y for Yes/No byte doesn't have one yet, so use %d ubyte doesn't have one yet, so use %d or %u short doesn't have one yet, so use %d ushort doesn't have one yet, so use %d or %u int %d uint %u long %l ulong doesn't have one yet, so use %u usize doesn't have one yet, so use %u float doesn't have one yet, so use %f double %f *ubyte %s String %S ptr/*WhateverType %p I'm planning on completing these specifiers to be something like:

name designation bool %b or %B for true/false, %y for yes/no, %Y for Yes/No byte %hhd or %hhi ubyte %hhu for numeric value, %c for character value short %hd or %hi ushort %hu int %d or %i uint %u long %ld or %li or %lld or %lli ulong %lu or %llu usize %zu float %hf double %f *ubyte %s String %S ptr/*WhateverType %p

@IsaacShelton I saw that you have changed something in data types specifiers (%...) at the last commits, now which one table of types is valid?

IsaacShelton commented 4 years ago

@t0md3an Yeah I finished implementing the rest of the specifiers, this is the full table:

name designation
bool %b or %B for true/false, %y for yes/no, %Y for Yes/No
byte %hhd or %hhi
ubyte %hhu for numeric value, %c for character value
short %hd or %hi
ushort %hu
int %d or %i
uint %u
long %ld or %li or %lld or %lli
ulong %lu or %llu
usize %zu
float %hf
double %f
*ubyte %s
String %S
ptr/*WhateverType %p

This of course only applies to the printf(String, arguments ...) version of printf and not printf(*ubyte, ...).

If runtime type information isn't disabled, then %d, %i, %u, and %f specifiers aren't picky about whether you give them the exact type they expect.

ghost commented 4 years ago

@IsaacShelton

1. How to printf **WhateverType? Like * %p?

2. How to printf List? Using it’s type?

3. What is ulong, ushort and usize and what difference between long, short and size?

4. What difference between byte and ubyte?

5. Why there is no unsigned float ufloat/unsigned float?

6. Can I do something like long long int in Adept?

Thanks

IsaacShelton commented 4 years ago

@t0md3an

  1. Yeah since **WhateverType is still just a pointer, you use %p.

  2. To printf List, you have to convert it to a String. With the latest build of AdeptImport you can do:

    
    import basics

func main { list List = getList() printf("list = %S\n", toString(list)) }

func getList List { list List repeat 10, list.add(idx) return list.commit() }

Otherwise, without using any recent stuff, you can just use an `each-in` loop to print each element:

import basics

func main { list List = getList() each int in list { printf("list[%d] = %d\n", idx, it) } }



3. To start off, here is a table of all the primitive types:

| Primitive Type | Bits | Signed-ness | Possible Values | C Equivalent (Roughly) | 
|----|----|----|----|----|
| `bool` | 1 bit | ~ | true or false | `bool` |
| `byte` | 8 bits | signed | -128..127 | `signed char` |
| `short` | 16 bits | signed |  -32,768..32,767 | `short` |
| `int` | 32 bits | signed | -2,147,483,648..2,147,483,647 | `int` |
| `long` | 64 bits | signed | -9e18..9,223,372,036,854,775,807 | `long long` |
| `ubyte` | 8 bits | unsigned | 0..255 | `unsigned char` |
| `ushort` | 16 bits | unsigned |  0..65,535 | `unsigned short` |
| `uint` | 32 bits | unsigned | 0..4,294,967,295 | `unsigned int ` |
| `ulong` | 64 bits | unsigned | 0..18,446,744,073,709,551,615 | `unsigned long long` |
| `usize` | 64 bits | unsigned | 0..18,446,744,073,709,551,615 | `size_t` |
| `float` | 32 bits | ~ | 3.4E +/- 38 (7 digits) | `float` |
| `double` | 64 bits | ~ | 1.7E +/- 308 (15 digits) | `double` |
| `ptr`/`*` | 64 bits | unsigned | Any Memory Address | `void*` / `*` / `[]` |

There are 4 main types. They are `byte`, `short`, `int`, and `long`. They are 8 bits, 16 bits, 32 bits, and 64 bits in size respectively. They can also be prefixed with `u` to make them unsigned. When they are unsigned, they lose the ability to hold negative numbers, but they gain the ability to hold more positive numbers. In addition to these types, we have `bool` which of course is a boolean that can hold true or false. We also have `float` and `double` which are the two floating point number options, which are 32 bits and 64 bits in size respectively. Then we also have `usize` which does NOT have a signed variant. It is used to hold lengths or sizes of things. The reason why there is no `size` type is because length and size measurements can never be negative, so we always use `usize`. And lastly we have the pointer types. Which includes `*` types and the special `ptr` type. The `ptr` type is a pointer to an unspecified type, just like `void*` is in C.

With that knowledge, we can now differentiate these types:

**`ulong`** is an unsigned 64-bit integer, which means it can hold positive integers up to 2^64-1. so values 0..18,446,744,073,709,551,615.

**`ushort`** is an unsigned 16-bit integer, which means it can hold positive integers up to 2^16-1, so values  0..65,535.

**`usize`** is an unsigned integer used to hold sizes or lengths, currently it's an unsigned 64-bit integer, so it's identical to `ulong`

**`short`** is signed 16-bit integer, which means it can hold positive and negative integers -32,768..32,767.

**`long`** is signed 64-bit integer, which means it can hold positive and negative integers -9,223,372,036,854,775,808..9,223,372,036,854,775,807.

**`size`** does not exist, since lengths and size measurements are always positive, we always use `usize`.

4. The difference is that `byte` is signed, where as `ubyte` is unsigned.

`byte` can hold values -128..127.

`ubyte` can hold values 0..255.

5. Because CPUs don't support unsigned floats. In 99% of cases, you want floats to be able to hold negative numbers.

6. `long long int` is a signed 64-bit integer in C (usually). In Adept we have `long`, which is the same thing.
ghost commented 4 years ago

@IsaacShelton Have you planned to allow this (() in syntax):

sizeof(...) // now only sizeof value, if I uses `()` it does not works
new(...)
delete(...)
other keywords with this syntax...