Added types

This commit is contained in:
Eduard Urbach 2024-08-05 18:47:24 +02:00
parent cd1119add2
commit 83661c5e7a
Signed by: akyoto
GPG Key ID: C874F672B1AF20C0
33 changed files with 113 additions and 92 deletions

View File

@ -5,7 +5,7 @@ main() {
collatz(12) collatz(12)
} }
collatz(x) { collatz(x Int) {
loop { loop {
if x & 1 == 0 { if x & 1 == 0 {
x /= 2 x /= 2

View File

@ -4,7 +4,7 @@ main() {
log.number(factorial(5)) log.number(factorial(5))
} }
factorial(x) { factorial(x Int) -> Int {
if x <= 1 { if x <= 1 {
return 1 return 1
} }

View File

@ -4,7 +4,7 @@ main() {
log.number(fibonacci(10)) log.number(fibonacci(10))
} }
fibonacci(x) { fibonacci(x Int) -> Int {
if x <= 1 { if x <= 1 {
return x return x
} }

View File

@ -5,7 +5,7 @@ main() {
fizzbuzz(15) fizzbuzz(15)
} }
fizzbuzz(n) { fizzbuzz(n Int) {
x := 1 x := 1
loop { loop {
@ -26,6 +26,6 @@ fizzbuzz(n) {
} }
} }
print(address, length) { print(address Pointer, length Int) {
sys.write(1, address, length) sys.write(1, address, length)
} }

View File

@ -4,7 +4,7 @@ main() {
log.number(gcd(1071, 462)) log.number(gcd(1071, 462))
} }
gcd(a, b) { gcd(a Int, b Int) -> Int {
loop { loop {
switch { switch {
a == b { return a } a == b { return a }

View File

@ -4,6 +4,6 @@ main() {
print("Hello\n", 6) print("Hello\n", 6)
} }
print(address, length) { print(address Pointer, length Int) {
sys.write(1, address, length) sys.write(1, address, length)
} }

View File

@ -22,7 +22,7 @@ main() {
} }
} }
isPrime(x) { isPrime(x Int) -> Int {
if x == 2 { if x == 2 {
return 1 return 1
} }

View File

@ -1,7 +1,7 @@
import mem import mem
import sys import sys
number(x) { number(x Int) {
length := 20 length := 20
buffer := mem.alloc(length) buffer := mem.alloc(length)
address, count := itoa(x, buffer, length) address, count := itoa(x, buffer, length)
@ -9,7 +9,7 @@ number(x) {
mem.free(buffer, length) mem.free(buffer, length)
} }
itoa(x, buffer, length) { itoa(x Int, buffer Pointer, length Int) -> (Pointer, Int) {
end := buffer + length end := buffer + length
tmp := end tmp := end
digit := 0 digit := 0

View File

@ -1,9 +1,9 @@
import sys import sys
alloc(length) { alloc(length Int) -> Pointer {
return sys.mmap(0, length, 0x1|0x2, 0x02|0x20|0x100) return sys.mmap(0, length, 0x1|0x2, 0x02|0x20|0x100)
} }
free(address, length) { free(address Pointer, length Int) -> Int {
return sys.munmap(address, length) return sys.munmap(address, length)
} }

View File

@ -1,71 +1,71 @@
read(fd, address, length) { read(fd Int, address Pointer, length Int) -> Int {
return syscall(0, fd, address, length) return syscall(0, fd, address, length)
} }
write(fd, address, length) { write(fd Int, address Pointer, length Int) -> Int {
return syscall(1, fd, address, length) return syscall(1, fd, address, length)
} }
open(file, flags, mode) { open(file Pointer, flags Int, mode Int) -> Int {
return syscall(2, file, flags, mode) return syscall(2, file, flags, mode)
} }
close(fd) { close(fd Int) -> Int {
return syscall(3, fd) return syscall(3, fd)
} }
mmap(address, length, protection, flags) { mmap(address Int, length Int, protection Int, flags Int) -> Int {
return syscall(9, address, length, protection, flags) return syscall(9, address, length, protection, flags)
} }
munmap(address, length) { munmap(address Pointer, length Int) -> Int {
return syscall(11, address, length) return syscall(11, address, length)
} }
clone(flags, stack) { clone(flags Int, stack Pointer) -> ThreadID {
return syscall(56, flags, stack) return syscall(56, flags, stack)
} }
exit(code) { exit(status Int) {
syscall(60, code) syscall(60, status)
} }
socket(family, type, protocol) { socket(family Int, type Int, protocol Int) -> Int {
return syscall(41, family, type, protocol) return syscall(41, family, type, protocol)
} }
accept(fd, address, length) { accept(fd Int, address Pointer, length Int) -> Int {
return syscall(43, fd, address, length) return syscall(43, fd, address, length)
} }
bind(fd, address, length) { bind(fd Int, address Pointer, length Int) -> Int {
return syscall(49, fd, address, length) return syscall(49, fd, address, length)
} }
listen(fd, backlog) { listen(fd Int, backlog Int) -> Int {
return syscall(50, fd, backlog) return syscall(50, fd, backlog)
} }
getcwd(buffer, length) { getcwd(buffer Pointer, length Int) -> Int {
return syscall(79, buffer, length) return syscall(79, buffer, length)
} }
chdir(path) { chdir(path Pointer) -> Int {
return syscall(80, path) return syscall(80, path)
} }
rename(old, new) { rename(old Pointer, new Pointer) -> Int {
return syscall(82, old, new) return syscall(82, old, new)
} }
mkdir(path, mode) { mkdir(path Pointer, mode Int) -> Int {
return syscall(83, path, mode) return syscall(83, path, mode)
} }
rmdir(path) { rmdir(path Pointer) -> Int {
return syscall(84, path) return syscall(84, path)
} }
unlink(file) { unlink(file Pointer) -> Int {
return syscall(87, file) return syscall(87, file)
} }

View File

@ -1,5 +1,26 @@
package errors package errors
var (
EmptySwitch = &Base{"Empty switch"}
ExpectedFunctionName = &Base{"Expected function name"}
ExpectedFunctionParameters = &Base{"Expected function parameters"}
ExpectedFunctionDefinition = &Base{"Expected function definition"}
ExpectedIfBeforeElse = &Base{"Expected an 'if' block before 'else'"}
InvalidNumber = &Base{"Invalid number"}
InvalidExpression = &Base{"Invalid expression"}
InvalidRune = &Base{"Invalid rune"}
InvalidStatement = &Base{"Invalid statement"}
MissingBlockStart = &Base{"Missing '{'"}
MissingBlockEnd = &Base{"Missing '}'"}
MissingExpression = &Base{"Missing expression"}
MissingGroupStart = &Base{"Missing '('"}
MissingGroupEnd = &Base{"Missing ')'"}
MissingMainFunction = &Base{"Missing main function"}
MissingOperand = &Base{"Missing operand"}
MissingType = &Base{"Missing type"}
NotImplemented = &Base{"Not implemented"}
)
// Base is the base class for errors that have no parameters. // Base is the base class for errors that have no parameters.
type Base struct { type Base struct {
Message string Message string

View File

@ -1,14 +0,0 @@
package errors
var (
EmptySwitch = &Base{"Empty switch"}
ExpectedIfBeforeElse = &Base{"Expected an 'if' block before 'else'"}
InvalidNumber = &Base{"Invalid number"}
InvalidExpression = &Base{"Invalid expression"}
InvalidRune = &Base{"Invalid rune"}
InvalidStatement = &Base{"Invalid statement"}
MissingExpression = &Base{"Missing expression"}
MissingMainFunction = &Base{"Missing main function"}
MissingOperand = &Base{"Missing operand"}
NotImplemented = &Base{"Not implemented"}
)

View File

@ -1,11 +0,0 @@
package errors
var (
MissingBlockStart = &Base{"Missing '{'"}
MissingBlockEnd = &Base{"Missing '}'"}
MissingGroupStart = &Base{"Missing '('"}
MissingGroupEnd = &Base{"Missing ')'"}
ExpectedFunctionName = &Base{"Expected function name"}
ExpectedFunctionParameters = &Base{"Expected function parameters"}
ExpectedFunctionDefinition = &Base{"Expected function definition"}
)

View File

@ -1,6 +1,7 @@
package scanner package scanner
import ( import (
"fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -153,8 +154,20 @@ func (s *Scanner) scanFile(path string, pkg string) error {
return errors.New(errors.ExpectedFunctionParameters, file, tokens[i].Position) return errors.New(errors.ExpectedFunctionParameters, file, tokens[i].Position)
} }
// Return type
if i < len(tokens) && tokens[i].Kind == token.ReturnType {
for i < len(tokens) && tokens[i].Kind != token.BlockStart {
i++
}
}
// Function definition // Function definition
for i < len(tokens) { for i < len(tokens) {
if tokens[i].Kind == token.ReturnType {
i++
continue
}
if tokens[i].Kind == token.BlockStart { if tokens[i].Kind == token.BlockStart {
blockLevel++ blockLevel++
i++ i++
@ -207,17 +220,18 @@ func (s *Scanner) scanFile(path string, pkg string) error {
name := tokens[nameStart].Text(contents) name := tokens[nameStart].Text(contents)
body := tokens[bodyStart:i] body := tokens[bodyStart:i]
function := core.NewFunction(pkg, name, file, body) function := core.NewFunction(pkg, name, file, body)
parameters := tokens[paramsStart:paramsEnd] parameters := tokens[paramsStart:paramsEnd]
count := 0 count := 0
err := expression.EachParameter(parameters, func(tokens token.List) error { err := expression.EachParameter(parameters, func(tokens token.List) error {
if len(tokens) != 1 { if len(tokens) < 2 {
return errors.New(errors.NotImplemented, file, tokens[0].Position) return errors.New(errors.MissingType, file, tokens[0].End())
} }
name := tokens[0].Text(contents) name := tokens[0].Text(contents)
dataType := tokens[1].Text(contents)
fmt.Println(dataType)
register := x64.CallRegisters[count] register := x64.CallRegisters[count]
uses := token.Count(function.Body, contents, token.Identifier, name) uses := token.Count(function.Body, contents, token.Identifier, name)

View File

@ -18,6 +18,7 @@ const (
BlockEnd // } BlockEnd // }
ArrayStart // [ ArrayStart // [
ArrayEnd // ] ArrayEnd // ]
ReturnType // ->
_operators // <operators> _operators // <operators>
Add // + Add // +
Sub // - Sub // -

View File

@ -30,9 +30,17 @@ func Tokenize(buffer []byte) List {
if len(tokens) == 0 || tokens[len(tokens)-1].IsOperator() || tokens[len(tokens)-1].IsExpressionStart() || tokens[len(tokens)-1].IsKeyword() { if len(tokens) == 0 || tokens[len(tokens)-1].IsOperator() || tokens[len(tokens)-1].IsExpressionStart() || tokens[len(tokens)-1].IsKeyword() {
tokens = append(tokens, Token{Kind: Negate, Position: i, Length: 1}) tokens = append(tokens, Token{Kind: Negate, Position: i, Length: 1})
} else { } else {
if i+1 < Position(len(buffer)) && buffer[i+1] == '=' { if i+1 < Position(len(buffer)) {
tokens = append(tokens, Token{Kind: SubAssign, Position: i, Length: 2}) switch buffer[i+1] {
i++ case '=':
tokens = append(tokens, Token{Kind: SubAssign, Position: i, Length: 2})
i++
case '>':
tokens = append(tokens, Token{Kind: ReturnType, Position: i, Length: 2})
i++
default:
tokens = append(tokens, Token{Kind: Sub, Position: i, Length: 1})
}
} else { } else {
tokens = append(tokens, Token{Kind: Sub, Position: i, Length: 1}) tokens = append(tokens, Token{Kind: Sub, Position: i, Length: 1})
} }
@ -212,10 +220,12 @@ func Tokenize(buffer []byte) List {
kind = Add kind = Add
case "+=": case "+=":
kind = AddAssign kind = AddAssign
case "-": // case "-":
kind = Sub // kind = Sub
case "-=": // case "-=":
kind = SubAssign // kind = SubAssign
// case "->":
// kind = ReturnType
case ".": case ".":
kind = Period kind = Period
case "/": case "/":

View File

@ -2,6 +2,6 @@ main() {
x := 1 + f(x) x := 1 + f(x)
} }
f(x) { f(x Int) -> Int {
return x return x
} }

View File

@ -70,14 +70,14 @@ main() {
if x == 0 { if x == 0 {
sys.exit(0) sys.exit(0)
} }
sys.exit(1) sys.exit(1)
} }
inc(x) { inc(x Int) -> Int {
return x + 1 return x + 1
} }
dec(x) { dec(x Int) -> Int {
return x - 1 return x - 1
} }

View File

@ -2,6 +2,6 @@ main() {
assert f(1) + f(2) + f(3) == 9 assert f(1) + f(2) + f(3) == 9
} }
f(x) { f(x Int) -> Int {
return x + 1 return x + 1
} }

View File

@ -12,6 +12,6 @@ main() {
} }
} }
f(x) { f(x Int) -> Int {
return x return x
} }

View File

@ -4,10 +4,10 @@ main() {
assert result == 10 assert result == 10
} }
div(x, y) { div(x Int, y Int) -> Int {
return x / y return x / y
} }
div10(x) { div10(x Int) -> Int {
return x / 10 return x / 10
} }

View File

@ -5,6 +5,6 @@ main() {
assert neg(256) == -256 assert neg(256) == -256
} }
neg(x) { neg(x Int) -> Int {
return -x return -x
} }

View File

@ -2,6 +2,6 @@ main() {
assert f(f(f(1))) == 4 assert f(f(f(1))) == 4
} }
f(x) { f(x Int) -> Int {
return x + 1 return x + 1
} }

View File

@ -2,7 +2,7 @@ main() {
f(10) f(10)
} }
f(new) { f(new Int) {
old := new old := new
new -= 1 new -= 1
assert new != old assert new != old

View File

@ -2,11 +2,11 @@ main() {
assert f(1, 2, 3) == 21 assert f(1, 2, 3) == 21
} }
f(x, y, z) { f(x Int, y Int, z Int) -> Int {
w := g(4, 5, 6) w := g(4, 5, 6)
return x + y + z + w return x + y + z + w
} }
g(x, y, z) { g(x Int, y Int, z Int) -> Int {
return x + y + z return x + y + z
} }

View File

@ -2,11 +2,11 @@ main() {
f(1, 2, 3, 4, 5, 6) f(1, 2, 3, 4, 5, 6)
} }
f(a, b, c, d, e, f) { f(a Int, b Int, c Int, d Int, e Int, f Int) {
return g(f, e, d, c, b, a) g(f, e, d, c, b, a)
} }
g(a, b, c, d, e, f) { g(a Int, b Int, c Int, d Int, e Int, f Int) {
assert a == 6 assert a == 6
assert b == 5 assert b == 5
assert c == 4 assert c == 4

View File

@ -2,11 +2,11 @@ main() {
assert f(1) == 3 assert f(1) == 3
} }
f(x) { f(x Int) -> Int {
y := g() y := g()
return x + y return x + y
} }
g() { g() -> Int {
return 2 return 2
} }

View File

@ -15,14 +15,14 @@ main() {
assert i == 1 + 4 assert i == 1 + 4
} }
reverse2(a, b) { reverse2(a Int, b Int) -> (Int, Int) {
return b, a return b, a
} }
reverse3(a, b, c) { reverse3(a Int, b Int, c Int) -> (Int, Int, Int) {
return c, b, a return c, b, a
} }
mix4(a, b, c, d) { mix4(a Int, b Int, c Int, d Int) -> (Int, Int, Int, Int) {
return d + a, c + b, b + c, a + d return d + a, c + b, b + c, a + d
} }

View File

@ -2,10 +2,10 @@ main() {
assert f(2) == 6 assert f(2) == 6
} }
f(x) { f(x Int) -> Int {
return x + 1 + g(x) return x + 1 + g(x)
} }
g(x) { g(x Int) -> Int {
return x + 1 return x + 1
} }

View File

@ -2,6 +2,6 @@ main() {
assert f(1) == 3 assert f(1) == 3
} }
f(x) { f(x Int) -> Int {
return x + 1 + x return x + 1 + x
} }

View File

@ -2,6 +2,6 @@ main() {
assert f(2, 3) == 25 assert f(2, 3) == 25
} }
f(x, y) { f(x Int, y Int) -> Int {
return (x + y) * (x + y) return (x + y) * (x + y)
} }

View File

@ -40,7 +40,7 @@ var programs = []struct {
{"modulo", "", "", 0}, {"modulo", "", "", 0},
{"modulo-assign", "", "", 0}, {"modulo-assign", "", "", 0},
{"div-split", "", "", 0}, {"div-split", "", "", 0},
{"64-bit", "", "", 0}, {"int64", "", "", 0},
{"negative", "", "", 0}, {"negative", "", "", 0},
{"negation", "", "", 0}, {"negation", "", "", 0},
{"square-sum", "", "", 0}, {"square-sum", "", "", 0},