Initial commit

pull/315/head
Alexander Medvednikov 2019-02-08 03:59:19 +01:00
parent 825419003a
commit 8dd6fb1766
9 changed files with 348 additions and 2 deletions

2
.gitattributes vendored 100644
View File

@ -0,0 +1,2 @@
*.v linguist-language=Go
website/* linguist-vendored

21
LICENSE 100644
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 Alexander Medvednikov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,3 +1,81 @@
# Official V repository
# The V Programming Language
V is going to be open-sourced in mid 2019.
V is going to be open-sourced in June 2019. Early access on April 15.
https://vlang.io
Documentation: https://vlang.io/docs
Twitter: https://twitter.com/vlang_io
 
## Fast compilation
V compiles 1.5 million lines of code per second per CPU core
```
cd doom3/
wc -l doom3.v # 458 713
time v doom3.v # 0.5s
```
[Compilation speed benchmark and comparison with other languages.](https://vlang.io/compilation_speed)
## Safety
- No global state
- No null
- No undefined values
- Option types
- Generics
- Immutability by default
- Partially pure functions
## C/C++ translation
V can translate your entire C/C++ project and offer you the safety, simplicity, and up to 200x compilation speed up.
```
std::vector<std::string> s;
s.push_back("V is ");
s.push_back("awesome");
std::cout << s.size();
```
```
s := []string
s << 'V is '
s << 'awesome'
println(s.len)
```
Read about translating Doom & Doom 3, LevelDB, SQLite (coming in March).
## 400 KB compiler with zero dependencies
The entire V language and its standard library is less than 400 KB. You can build V in 0.3 seconds.
## Performance
- As fast as C
- Minimal amount of allocations
- Built-in serialization without reflection
## Hot code reloading
Get your changes instantly without recompiling!
Since you also don't have to waste time to get to the state you are working on after every compilation, this can save a lot of precious minutes of your development time.
[Demonstration of hot code reloading.](https://volt-app.com/img/lang.webm)
## Simple language for building maintainable programs
You can learn the entire language by going through the documentation in half an hour.
Despite being simple, it gives a lot of power to the developer. Anything you can do in other languages, you can do in V.
## REPL
```
v
>> data := http.get('https://vlang.io/utc_now')?
>> data
'1551205308'
```
## Native cross platform UI library
Build native apps that look native. You no longer need to embed a browser to develop cross platform apps quickly.
## Run everywhere
V can compile to (human readable) C, so you get the great platform support and optimization of gcc and Clang.

45
base64/base64.v 100644
View File

@ -0,0 +1,45 @@
module base64
const (
INDEX = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62, 63, 62, 62, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0,
0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 63, 0, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
47, 48, 49, 50, 51]
)
fn decode(data string) string {
p := data.str
len := data.len
mut pad := 0
if len > 0 && (len % 4 != 0 || p[len - 1] == `=`) {
pad = 1
}
L := ((len + 3) / 4 - pad) * 4
str_len := L / 4 * 3 + pad
mut str := malloc(str_len + 2)
mut j := 0
for i := 0; i < L; i += 4 {
n := (INDEX[p[i]] << 18) | (INDEX[p[i + 1]] << 12) |
(INDEX[p[i + 2]] << 6) | (INDEX[p[i + 3]])
str[j] = n >> 16
j++
str[j] = n >> 8 & 0xff
j++
str[j] = n & 0xff
j++
}
if pad > 0 {
mut nn := (INDEX[p[L]] << 18) | (INDEX[p[L + 1]] << 12)
str[str_len - 1] = nn >> 16
if len > L + 2 && p[L + 2] != `=` {
nn = nn | (INDEX[p[L + 2]] << 6)
str[str_len] = nn >> 8 & 0xff
}
}
str[str_len + 1] = `\0`
return string(str)
}

View File

@ -0,0 +1,8 @@
import base64
fn test_decode() {
assert base64.decode('TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=')
== 'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.'
}

View File

@ -0,0 +1,35 @@
// Please share your thoughts, suggestions, questions, etc here:
// https://github.com/vlang-io/V/issues/3
// I'm very interested in your feedback.
import http
import json
import runtime
struct Story {
title string
}
// Fetches top HN stories in 8 coroutines
fn main() {
resp := http.get('https://hacker-news.firebaseio.com/v0/topstories.json')?
ids := json.decode([]int, resp.body)?
mut cursor := 0
for _ in 0..8 {
go fn() {
for {
lock { // Without this lock the program will not compile
if cursor >= ids.len {
break
}
id := ids[cursor]
cursor++
}
url := 'https://hacker-news.firebaseio.com/v0/item/$id.json'
resp := http.get(url)?
story := json.decode(Story, resp.body)?
println(story.title)
}
}()
}
runtime.wait() // Waits for all coroutines to finish
}

View File

@ -0,0 +1,42 @@
// Please share your thoughts, suggestions, questions, etc here:
// https://github.com/vlang-io/V/issues/3
// I'm very interested in your feedback.
module main
struct User { /* ... */ }
struct Post { /* ... */ }
struct DB { /* ... */ }
struct Repo <T> {
db DB
}
// Generic code is notoriously verbose. To reduce clutter, V doesn't require you
// to add `<T>` every time, since it already knows that Repo is a generic type.
fn new_repo<T>(db DB) Repo {
return Repo<T>{db: db}
}
// This is a generic function. V will generate it for every type it's used with.
fn (r Repo) find_by_id(id int) T? { // `?` means the function returns an optional
table_name := T.name // in this example getting the name of the type gives us the table name
return r.db.query_one<T>('select * from $table_name where id = ?', id)
}
fn main() {
db := new_db()
users_repo := new_repo<User>(db)
// I'm also considering passing the type as an argument
// users_repo := new_repo(User, db)
posts_repo := new_repo<Post>(db)
user := users_repo.find_by_id(1) or {
eprintln('User not found')
return
}
post := posts_repo.find_by_id(1) or {
eprintln('Post not found')
return
}
}

View File

@ -0,0 +1,42 @@
// Please share your thoughts, suggestions, questions, etc here:
// https://github.com/vlang-io/V/issues/3
// I'm very interested in your feedback.
module main
import ui // Native cross platform ui toolkit (uses Cocoa, win32, GTK+)
// There are no globals, so we have to use a context struct
struct Context {
input ui.TextBox // this uses native controls (NSTextView on macOS, edit HWND on Windows)
names []string // let's log the names to demonstrate how arrays work
}
fn main() {
wnd := ui.new_window(ui.WindowCfg{ // V has no default arguments and overloading.
width: 600 // All stdlib functions with many args use Cfg wrappers.
height: 300
title: 'hello world'
})
ctx := Context{
input: ui.new_textbox(wnd)
// we don't need to initialize the names array, it's done automatically
}
ctx.input.set_placeholder('Enter your name')
btn := ui.new_button(wnd, 'Click me', ctx.btn_click)
for {
ui.wait_events()
}
}
fn (ctx mut Context) btn_click() {
name := ctx.input.text()
ctx.input.hide()
println('current list of names: $ctx.names') // >> current list of names: [ "Bob", "Alex" ]
ui.alert('Hello, $name!')
if ctx.names.contains(name) {
ui.alert('I already greeted you ;)')
}
ctx.names << name
}

73
examples/users.v 100644
View File

@ -0,0 +1,73 @@
// Please share your thoughts, suggestions, questions, etc here:
// https://github.com/vlang-io/V/issues/3
// I'm very interested in your feedback.
module main
import json // V will automatically insert missing imports (like the goimports tool)
import http
// Right now V requires all consts to be uppercase.
// I'm still not certain about this.
const API_URL = 'https://vlang.io/users.json'
// V will generate json.encode and json.decode functions for this type since
// `json.decode([]User, ...)` is called later. This results in better
// performance, since reflection is not used.
struct User {
name string // V will automatically format and align your code.
age int // No need to use an additional tool.
is_registered bool
}
fn main() {
// `http.get()` returns an optional string.
// V optionals combine the features of Rust's Option<T> and Result<T>.
// We must unwrap all optionals with `or`, otherwise V will complain.
s := http.get(API_URL) or {
// `err` is a reserved variable (not a global) that
// contains an error message if there is one
eprintln('Failed to fetch "users.json": $err')
// `or` blocks must end with `return`, `break`, or `continue`
return
}
// Types can be passed as arguments
users := json.decode([]User, s) or {
eprintln('Failed to parse users.json')
return
}
// Encoding JSON doesn't require a type, since V knows what type
// the variable `users` has
println(json.encode(users))
// Please note the difference between V and Go:
// when there's only one variable, it's a value, not an index.
for user in users {
println('$user.name: $user.age')
}
// `for` loop has an alternative form when an index is required:
for i, user in users {
println('$i) $user')
if !user.can_register() {
// V allows both ' and " to denote strings.
// However, for consistency V will replace " with '
// unless the string contains an apostrophe.
println("Can't register")
}
}
}
// The method declaration is the same as in Go.
// There is one big difference. Here `u` can be either passed by value (User)
// or by reference (&User). The compiler will make the right decision
// depending on the size of the User struct. You no longer have to remember
// which one to use. It works here because `u` can't be modified (it's not
// marked as `mut`).
fn (u User) can_register() bool {
return u.age >= 16
}
// Here `u` can be modified and it will always be a reference.
fn (u mut User) register() {
u.is_registered = true
}