Skip to content

Commit

Permalink
Add classes to header generation
Browse files Browse the repository at this point in the history
  • Loading branch information
vyPal committed Jan 8, 2024
1 parent 658f982 commit 7cf83b3
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 30 deletions.
23 changes: 23 additions & 0 deletions example/caffeine.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* This file was automatically generated by CaffeineC.
* Do not edit this file directly.
*/
#ifndef CAFFEINEC_H
#define CAFFEINEC_H
long printf(char * fmt);
long long testing();
char * malloc(long long size);
class SomeClass
{
private:
long long something;
public:
void constructor();
void inc();
void dec();
long long get();
void set(long long newValue);
void add(long long toAdd);
void sub(long long toSub);
};
#endif
25 changes: 25 additions & 0 deletions example/src/use_externally.cffc
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,29 @@ extern vararg func printf(fmt: *i8): i32;
export func testing(): i64 {
printf("Hello, World!\n");
return 0;
}

export class SomeClass {
private something: i64;
func constructor() {
this.something = 0;
}
func inc() {
this.something = this.something + 1;
}
func dec() {
this.something = this.something - 1;
}
func get(): i64 {
return this.something;
}
func set(newValue: i64) {
this.something = newValue;
}
func add(toAdd: i64) {
this.something = this.something + toAdd;
}
func sub(toSub: i64) {
this.something = this.something + toSub;
}
}
101 changes: 101 additions & 0 deletions src/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strings"
"sync"

"github.com/fatih/color"
Expand Down Expand Up @@ -364,6 +365,9 @@ func writeHeader(f *os.File, comp *compiler.Compiler) error {
}

for _, fn := range comp.Module.Funcs {
if strings.Count(fn.Name(), ".") > 0 {
continue
}
_, err = f.WriteString(convertCffTypeToCType(fn.Sig.RetType) + " ")
if err != nil {
return err
Expand Down Expand Up @@ -414,6 +418,103 @@ func writeHeader(f *os.File, comp *compiler.Compiler) error {
}
}

for _, c := range comp.Module.TypeDefs {
_, err = f.WriteString("class " + c.Name() + "\n{\nprivate:\n")
if err != nil {
return err
}

for _, field := range comp.StructFields[c.Name()] {
if !field.Private {
continue
}
_, err = f.WriteString(convertCffTypeToCType(comp.Context.StringToType(field.Type)) + " " + field.Name + ";\n")
if err != nil {
return err
}
}

_, err = f.WriteString("public:\n")
if err != nil {
return err
}

for _, field := range comp.StructFields[c.Name()] {
if field.Private {
continue
}
_, err = f.WriteString(convertCffTypeToCType(comp.Context.StringToType(field.Type)) + " " + field.Name + ";\n")
if err != nil {
return err
}
}

for _, fn := range comp.Module.Funcs {
var parts []string
if strings.Count(fn.Name(), ".") == 0 {
continue
} else {
parts = strings.Split(fn.Name(), ".")
if parts[0] != c.Name() {
continue
}
}
_, err = f.WriteString(convertCffTypeToCType(fn.Sig.RetType) + " ")
if err != nil {
return err
}

_, err = f.WriteString(parts[1])
if err != nil {
return err
}

_, err = f.WriteString("(")
if err != nil {
return err
}

for i, param := range fn.Sig.Params[1:] {
_, err = f.WriteString(convertCffTypeToCType(param))
if err != nil {
return err
}

_, err = f.WriteString(" ")
if err != nil {
return err
}

_, err = f.WriteString(fn.Params[i+1].Name())
if err != nil {
return err
}

if i != len(fn.Sig.Params)-2 {
_, err = f.WriteString(", ")
if err != nil {
return err
}
}
}

_, err = f.WriteString(")")
if err != nil {
return err
}

_, err = f.WriteString(";\n")
if err != nil {
return err
}
}

_, err = f.WriteString("};\n")
if err != nil {
return err
}
}

_, err = f.WriteString("#endif\n")
if err != nil {
return err
Expand Down
22 changes: 11 additions & 11 deletions src/lib/compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,9 @@ func (c *Compiler) ImportAll(path string, ctx *Context) error {
if s.Export.FunctionDefinition != nil {
var params []*ir.Param
for _, p := range s.Export.FunctionDefinition.Parameters {
params = append(params, ir.NewParam(p.Name, ctx.stringToType(p.Type)))
params = append(params, ir.NewParam(p.Name, ctx.StringToType(p.Type)))
}
fn := c.Module.NewFunc(s.Export.FunctionDefinition.Name, ctx.stringToType(s.Export.FunctionDefinition.ReturnType), params...)
fn := c.Module.NewFunc(s.Export.FunctionDefinition.Name, ctx.StringToType(s.Export.FunctionDefinition.ReturnType), params...)
ctx.SymbolTable[s.Export.FunctionDefinition.Name] = fn
} else if s.Export.ClassDefinition != nil {
cStruct := types.NewStruct()
Expand All @@ -159,19 +159,19 @@ func (c *Compiler) ImportAll(path string, ctx *Context) error {
ctx.structNames[cStruct] = s.Export.ClassDefinition.Name
for _, st := range s.Export.ClassDefinition.Body {
if st.FieldDefinition != nil {
cStruct.Fields = append(cStruct.Fields, ctx.stringToType(st.FieldDefinition.Type))
cStruct.Fields = append(cStruct.Fields, ctx.StringToType(st.FieldDefinition.Type))
ctx.Compiler.StructFields[s.Export.ClassDefinition.Name] = append(ctx.Compiler.StructFields[s.Export.ClassDefinition.Name], st.FieldDefinition)
} else if st.FunctionDefinition != nil {
f := st.FunctionDefinition
var params []*ir.Param
params = append(params, ir.NewParam("this", types.NewPointer(cStruct)))
for _, arg := range f.Parameters {
params = append(params, ir.NewParam(arg.Name, ctx.stringToType(arg.Type)))
params = append(params, ir.NewParam(arg.Name, ctx.StringToType(arg.Type)))
}

fn := ctx.Module.NewFunc(s.Export.ClassDefinition.Name+"."+f.Name, ctx.stringToType(f.ReturnType), params...)
fn := ctx.Module.NewFunc(s.Export.ClassDefinition.Name+"."+f.Name, ctx.StringToType(f.ReturnType), params...)
fn.Sig.Variadic = false
fn.Sig.RetType = ctx.stringToType(f.ReturnType)
fn.Sig.RetType = ctx.StringToType(f.ReturnType)

ctx.SymbolTable[s.Export.ClassDefinition.Name+"."+f.Name] = fn
}
Expand Down Expand Up @@ -204,9 +204,9 @@ func (c *Compiler) ImportAs(path string, symbols map[string]string, ctx *Context
if newname, ok := symbols[s.Export.FunctionDefinition.Name]; ok {
var params []*ir.Param
for _, p := range s.Export.FunctionDefinition.Parameters {
params = append(params, ir.NewParam(p.Name, ctx.stringToType(p.Type)))
params = append(params, ir.NewParam(p.Name, ctx.StringToType(p.Type)))
}
fn := c.Module.NewFunc(s.Export.FunctionDefinition.Name, ctx.stringToType(s.Export.FunctionDefinition.ReturnType), params...)
fn := c.Module.NewFunc(s.Export.FunctionDefinition.Name, ctx.StringToType(s.Export.FunctionDefinition.ReturnType), params...)
if newname == "" {
newname = s.Export.FunctionDefinition.Name
}
Expand All @@ -220,13 +220,13 @@ func (c *Compiler) ImportAs(path string, symbols map[string]string, ctx *Context
cStruct := types.NewStruct()
for _, st := range s.Export.ClassDefinition.Body {
if st.FieldDefinition != nil {
cStruct.Fields = append(cStruct.Fields, ctx.stringToType(st.FieldDefinition.Type))
cStruct.Fields = append(cStruct.Fields, ctx.StringToType(st.FieldDefinition.Type))
} else if st.FunctionDefinition != nil {
var params []*ir.Param
for _, p := range st.FunctionDefinition.Parameters {
params = append(params, ir.NewParam(p.Name, ctx.stringToType(p.Type)))
params = append(params, ir.NewParam(p.Name, ctx.StringToType(p.Type)))
}
fn := c.Module.NewFunc(st.FunctionDefinition.Name, ctx.stringToType(st.FunctionDefinition.ReturnType), params...)
fn := c.Module.NewFunc(st.FunctionDefinition.Name, ctx.StringToType(st.FunctionDefinition.ReturnType), params...)
ctx.SymbolTable[newname+"."+st.FunctionDefinition.Name] = fn
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib/compiler/expressions.go
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,8 @@ func (ctx *Context) compileSubIdentifier(fieldType types.Type, pointer value.Val
if field == nil {
return nil, nil, false, posError(sub.Pos, "Field %s not found in struct %s", sub.Name, elemtypename)
}
fieldPtr := ctx.NewGetElementPtr(ctx.stringToType(field.Type), pointer, constant.NewInt(types.I32, int64(nfield)))
return ctx.compileSubIdentifier(ctx.stringToType(field.Type), fieldPtr, sub.Sub)
fieldPtr := ctx.NewGetElementPtr(ctx.StringToType(field.Type), pointer, constant.NewInt(types.I32, int64(nfield)))
return ctx.compileSubIdentifier(ctx.StringToType(field.Type), fieldPtr, sub.Sub)
}
return fieldType, pointer, false, nil
}
Expand Down
34 changes: 18 additions & 16 deletions src/lib/compiler/statements.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,29 @@ func (ctx *Context) compileExternalFunction(v *parser.ExternalFunctionDefinition
if v.ReturnType == "" {
retType = types.Void
} else {
retType = ctx.stringToType(v.ReturnType)
retType = ctx.StringToType(v.ReturnType)
}
var args []*ir.Param
for _, arg := range v.Parameters {
args = append(args, ir.NewParam(arg.Name, ctx.stringToType(arg.Type)))
args = append(args, ir.NewParam(arg.Name, ctx.StringToType(arg.Type)))
}

fn := ctx.Module.NewFunc(v.Name, retType, args...)
fn.Sig.Variadic = v.Variadic
}

func (ctx *Context) compileExternalVariable(v *parser.ExternalVariableDefinition) {
globalV := ctx.Module.NewGlobal(v.Name, ctx.stringToType(v.Type))
globalV := ctx.Module.NewGlobal(v.Name, ctx.StringToType(v.Type))
globalV.ExternallyInitialized = true
globalV.Init = constant.NewZeroInitializer(ctx.stringToType(v.Type))
globalV.Init = constant.NewZeroInitializer(ctx.StringToType(v.Type))
fmt.Println(globalV.Type())
ctx.vars[v.Name] = globalV
}

func (ctx *Context) compileVariableDefinition(v *parser.VariableDefinition) (Name string, Type types.Type, Value value.Value, Err error) {
// If there is no assignment, create an uninitialized variable
if v.Assignment == nil {
valType := ctx.stringToType(v.Type)
valType := ctx.StringToType(v.Type)
alloc := ctx.NewAlloca(valType)
ctx.NewStore(constant.NewZeroInitializer(valType), alloc)
ctx.vars[v.Name] = alloc
Expand Down Expand Up @@ -151,12 +151,12 @@ func (ctx *Context) compileAssignment(a *parser.Assignment) (Name string, Value
func (ctx *Context) compileFunctionDefinition(f *parser.FunctionDefinition) (Name string, ReturnType types.Type, Args []*ir.Param, err error) {
var params []*ir.Param
for _, arg := range f.Parameters {
params = append(params, ir.NewParam(arg.Name, ctx.stringToType(arg.Type)))
params = append(params, ir.NewParam(arg.Name, ctx.StringToType(arg.Type)))
}

fn := ctx.Module.NewFunc(f.Name, ctx.stringToType(f.ReturnType), params...)
fn := ctx.Module.NewFunc(f.Name, ctx.StringToType(f.ReturnType), params...)
fn.Sig.Variadic = f.Variadic
fn.Sig.RetType = ctx.stringToType(f.ReturnType)
fn.Sig.RetType = ctx.StringToType(f.ReturnType)
block := fn.NewBlock("")
nctx := NewContext(block, ctx.Compiler)
ctx.SymbolTable[f.Name] = fn
Expand All @@ -168,14 +168,14 @@ func (ctx *Context) compileFunctionDefinition(f *parser.FunctionDefinition) (Nam
}
}
if nctx.Term == nil {
if ctx.stringToType(f.ReturnType).Equal(types.Void) {
if ctx.StringToType(f.ReturnType).Equal(types.Void) {
nctx.NewRet(nil)
} else {
return "", nil, nil, posError(f.Pos, "Function `%s` does not return a value", f.Name)
}
}

return f.Name, ctx.stringToType(f.ReturnType), params, nil
return f.Name, ctx.StringToType(f.ReturnType), params, nil
}

func (ctx *Context) compileClassDefinition(c *parser.ClassDefinition) (Name string, TypeDef *types.StructType, Methods []ir.Func, err error) {
Expand All @@ -186,11 +186,13 @@ func (ctx *Context) compileClassDefinition(c *parser.ClassDefinition) (Name stri

for _, s := range c.Body {
if s.FieldDefinition != nil {
classType.Fields = append(classType.Fields, ctx.stringToType(s.FieldDefinition.Type))
classType.Fields = append(classType.Fields, ctx.StringToType(s.FieldDefinition.Type))
ctx.Compiler.StructFields[c.Name] = append(ctx.Compiler.StructFields[c.Name], s.FieldDefinition)
} else if s.FunctionDefinition != nil {
err := ctx.compileClassMethodDefinition(s.FunctionDefinition, c.Name, classType)
return "", nil, []ir.Func{}, err
if err != nil {
return "", nil, []ir.Func{}, err
}
}
}

Expand All @@ -201,12 +203,12 @@ func (ctx *Context) compileClassMethodDefinition(f *parser.FunctionDefinition, c
var params []*ir.Param
params = append(params, ir.NewParam("this", types.NewPointer(ctype)))
for _, arg := range f.Parameters {
params = append(params, ir.NewParam(arg.Name, ctx.stringToType(arg.Type)))
params = append(params, ir.NewParam(arg.Name, ctx.StringToType(arg.Type)))
}

fn := ctx.Module.NewFunc(cname+"."+f.Name, ctx.stringToType(f.ReturnType), params...)
fn := ctx.Module.NewFunc(cname+"."+f.Name, ctx.StringToType(f.ReturnType), params...)
fn.Sig.Variadic = false
fn.Sig.RetType = ctx.stringToType(f.ReturnType)
fn.Sig.RetType = ctx.StringToType(f.ReturnType)
block := fn.NewBlock("")
nctx := NewContext(block, ctx.Compiler)
for _, stmt := range f.Body {
Expand All @@ -216,7 +218,7 @@ func (ctx *Context) compileClassMethodDefinition(f *parser.FunctionDefinition, c
}
}
if nctx.Term == nil {
if ctx.stringToType(f.ReturnType).Equal(types.Void) {
if ctx.StringToType(f.ReturnType).Equal(types.Void) {
nctx.NewRet(nil)
} else {
cli.Exit(color.RedString("Error: Method `%s` of class `%s` does not return a value", f.Name, cname), 1)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/compiler/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func posError(pos lexer.Position, message string, args ...interface{}) error {
return cli.Exit(color.RedString("%s at %s:%d:%d", fmt.Sprintf(message, args...), pos.Filename, pos.Line, pos.Column), 1)
}

func (ctx *Context) stringToType(name string) types.Type {
func (ctx *Context) StringToType(name string) types.Type {
switch name {
// Standard types
case "int":
Expand Down

0 comments on commit 7cf83b3

Please sign in to comment.