Skip to content
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion apps/docs/components/Code/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ hi bhai
bhai ye hai a = 3;
bhai ye hai b = 0;

apna funda square(x){
rakh le bhai x*x;
}

jab tak bhai (b < 5) {
bol bhai b;
bol bhai square(b);

agar bhai (b == a) {
bol bhai "b is equal to a";
Expand Down
16 changes: 16 additions & 0 deletions apps/docs/components/Documentation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,22 @@ bye bhai
} warna bhai {
bol bhai "a is greater than or equal to 25";
}
bye bhai
`
},
{
name: "Function",
description: (
<>
Define function using <code className="language-cpp">apna funda</code> then the funcrtion name and parameters within ( ), blocks are executed and the return value can be provided using <code className="language-cpp">rakh le bhai</code>.
</>
),
code: `hi bhai
apna funda test(c){
bol bhai c;
rakh le bhai "return bhi "+c;
}
bol bhai test("kam kiya bhai");
bye bhai
`
},
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/components/common/syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const bhaiLangSyntax = languages.extend("clike", {
pattern: /(["'])((?:\\\1|(?:(?!\1)).)*)(\1)/,
greedy: true,
},
keyword: /\b(?:hi bhai|bye bhai|bol bhai|bhai ye hai|nalla|agar bhai|nahi to bhai|warna bhai|jab tak bhai|bas kar bhai|agla dekh bhai)\b/,
keyword: /\b(?:hi bhai|bye bhai|bol bhai|bhai ye hai|nalla|agar bhai|nahi to bhai|warna bhai|jab tak bhai|bas kar bhai|agla dekh bhai|apna funda|rakh le bhai)\b/,
boolean: /\b(?:sahi|galat)\b/,
number: /(?:(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[-+]?\d+)?)i?/i,
operator:
Expand Down
86 changes: 86 additions & 0 deletions packages/interpreter/src/components/dataClass.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
export enum DataTypes{
Null='null',
Boolean='boolean',
Numeric='numeric',
String='string',
Callable='callable',
}
export class DataObject {
protected _value: any;
protected _type:string;
public isDataObject:boolean;

constructor(value: any,type:string) {
this._value = value;
this._type = type;
this.isDataObject=true;
}

getValue(): any {
return this._value;
}
getType():string{
return this._type;
}
getStringValue():string{
return this._value.toString();
}
}

export class BooleanObject extends DataObject{
constructor(value: boolean) {
super(value,DataTypes.Boolean);
}
getStringValue(): string {
return this._value?"sahi":"galat";
}
}

export class NumericObject extends DataObject{
constructor(value: number) {
super(value,DataTypes.Numeric);
}
}

export class StringObject extends DataObject{
constructor(value: string) {
super(value,DataTypes.String);
}
}

export class NullObject extends DataObject{
constructor() {
super(null,DataTypes.Null);
}
getStringValue(): string {
return "nalla";
}
}

export class CallableObject extends DataObject{
constructor(value: any) {
super(value,DataTypes.Callable);
}
}

export function sanatizeData(data:any|unknown):DataObject{
if((data==null)||(data==undefined)){
return new NullObject();
}
if(typeof data=='boolean'){
return new BooleanObject(data);
}
if(typeof data=='number'){
return new NumericObject(data);
}
if(typeof data=='string'){
return new StringObject(data);
}
if(typeof data=='function'){
return new CallableObject(data);
}
if(data.isDataObject==true){
return data as DataObject;
}
else throw new Error(`Ye kya kar raha hai: "${data}" sahi nhi hai. ye konsa data type hai bhai`);
}
34 changes: 29 additions & 5 deletions packages/interpreter/src/components/scope.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,40 @@
import RuntimeException from "../exceptions/runtimeException";
import { DataObject, NullObject, sanatizeData } from "./dataClass";


export default class Scope {
_variables: Map<string, unknown> = new Map();
_variables: Map<string, DataObject> = new Map();
_isLoop = false;
_isFunction=false;
_isBreakStatement = false;
_isContinueStatement = false;
_parentScope: Scope | null;
_isReturnStatement=false;
_returnVal:any=null;

constructor(parentScope: Scope | null) {
this._parentScope = parentScope;
}

isFunction(){
return this._isFunction;
}

setFunction(isFunction:boolean){
this._isFunction=isFunction;
}
setReturnStatement(isReturnStatement: boolean,returnValue:any) {
this._isReturnStatement=isReturnStatement;
this._returnVal=returnValue;
}
isReturnStatement() {
return this._isReturnStatement;
}
getReturnValue(){
if(!this._returnVal) this._returnVal=new NullObject();
return this._returnVal;
}

isLoop() {
return this._isLoop;
}
Expand All @@ -36,9 +59,10 @@ export default class Scope {
return this._isContinueStatement;
}

get(identifier: string): unknown {
get(identifier: string): DataObject {
if (this._variables.has(identifier)) {
return this._variables.get(identifier);
let value = sanatizeData(this._variables.get(identifier));
return value;
}

if (this._parentScope !== null) {
Expand All @@ -48,7 +72,7 @@ export default class Scope {
throw new RuntimeException(`Variable "${identifier}" bana to le pehle.`);
}

assign(identifier: string, value: unknown) {
assign(identifier: string, value: DataObject) {
if (this._variables.has(identifier)) {
this._variables.set(identifier, value);
return;
Expand All @@ -64,7 +88,7 @@ export default class Scope {
);
}

declare(identifier: string, value: unknown) {
declare(identifier: string, value: DataObject) {
if (this._variables.has(identifier)) {
throw new RuntimeException(
`Variable "${identifier}" pehle se exist karta hai bhai. Check karle.`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import NallaPointerException from "../../exceptions/nallaPointerException";
import RuntimeException from "../../exceptions/runtimeException";
import { getOperationValue } from "../../helpers";
import InterpreterModule from "../../module/interpreterModule";
import { DataObject, DataTypes, NullObject } from "../dataClass";


export default class AssignmentExpression implements Visitor {
Expand All @@ -16,14 +17,15 @@ export default class AssignmentExpression implements Visitor {
);

let identifier = node.left.name;
let value: unknown;
let value: DataObject|null|void=null;
const currentScope = InterpreterModule.getCurrentScope();

if (node.right) {
value = InterpreterModule.getVisitor(node.right.type).visitNode(
node.right
);
}
if(value==null) value =new NullObject()

if (identifier && node.operator) {
const left = currentScope.get(identifier);
Expand All @@ -33,7 +35,7 @@ export default class AssignmentExpression implements Visitor {
`Nalla operand ni jamta "${node.operator}" ke sath`
);

if ((left === true || left === false) && node.operator !== "=")
if (left.getType()==DataTypes.Boolean && node.operator !== "=")
throw new RuntimeException(
`Boolean operand ni jamta "${node.operator}" ke sath`
);
Expand All @@ -46,5 +48,6 @@ export default class AssignmentExpression implements Visitor {

return currentScope.get(identifier);
}

}
}
42 changes: 7 additions & 35 deletions packages/interpreter/src/components/visitor/binaryExpression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import NallaPointerException from "../../exceptions/nallaPointerException";
import RuntimeException from "../../exceptions/runtimeException";
import { getOperationValue } from "../../helpers";
import InterpreterModule from "../../module/interpreterModule";
import { sanatizeData } from "../dataClass";


export default class BinaryExpression implements Visitor {
Expand All @@ -16,28 +17,17 @@ export default class BinaryExpression implements Visitor {
);
}

let left, right;

// handling logical & binary both at the same place as both operate on two operands
if (node.type == NodeType.BinaryExpression) {
if (node.operator !== "==" && node.operator !== "!=") {
this._checkNalla(node);
this._checkBoolean(node);
}
left = this._getNodeValue(node.left);
right = this._getNodeValue(node.right);
} else if (node.type == NodeType.LogicalExpression) {
this._checkNalla(node);

left = node.left.type == NodeType.BooleanLiteral ? (node.left.value == "sahi" ? true : false) : InterpreterModule.getVisitor(node.left.type).visitNode(
node.left
);

right = node.right.type == NodeType.BooleanLiteral ? (node.right.value == "sahi" ? true : false) : InterpreterModule.getVisitor(node.right.type).visitNode(
node.right
);

}
const left = sanatizeData(InterpreterModule.getVisitor(node.left.type).visitNode(node.left));
const right = sanatizeData(InterpreterModule.getVisitor(node.right.type).visitNode(node.right));
return getOperationValue({ left, right }, node.operator);
}

Expand All @@ -60,12 +50,12 @@ export default class BinaryExpression implements Visitor {

if (node.left.type === NodeType.IdentifierExpression && node.left.name) {
const value = InterpreterModule.getCurrentScope().get(node.left.name);
if (value === null) throw nallaException;
if (value === null||value.getValue()==null) throw nallaException;
}

if (node.right.type === NodeType.IdentifierExpression && node.right.name) {
const value = InterpreterModule.getCurrentScope().get(node.right.name);
if (value === null) throw nallaException;
if (value === null||value.getValue()==null) throw nallaException;
}
}

Expand All @@ -89,30 +79,12 @@ export default class BinaryExpression implements Visitor {

if (node.left.type === NodeType.IdentifierExpression && node.left.name) {
const value = InterpreterModule.getCurrentScope().get(node.left.name);
if (value === true || value === false) throw runtimeException;
if (value.getValue() === true || value.getValue() === false) throw runtimeException;
}

if (node.right.type === NodeType.IdentifierExpression && node.right.name) {
const value = InterpreterModule.getCurrentScope().get(node.right.name);
if (value === true || value === false) throw runtimeException;
if (value.getValue() === true || value.getValue() === false) throw runtimeException;
}
}

private _getNodeValue(node: ASTNode) {

if (node.type === NodeType.NullLiteral)
return null;

if (node.type === NodeType.BooleanLiteral) {
return node.value === "sahi" ? true : false;
}

if (node.type === NodeType.IdentifierExpression && node.name)
return InterpreterModule.getCurrentScope().get(node.name);

return InterpreterModule.getVisitor(node.type).visitNode(
node
);
}

}
6 changes: 6 additions & 0 deletions packages/interpreter/src/components/visitor/blockStatement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default class BlockStatement implements Visitor {
InterpreterModule.setCurrentScope(new Scope(parentScope));

InterpreterModule.getCurrentScope().setLoop(parentScope.isLoop());
InterpreterModule.getCurrentScope().setFunction(parentScope.isFunction());

if (Array.isArray(node.body)) {
node.body.every((statement: ASTNode) => {
Expand All @@ -21,6 +22,11 @@ export default class BlockStatement implements Visitor {
parentScope.setContinueStatement(true);
return false;
}
if(InterpreterModule.getCurrentScope().isReturnStatement()&&parentScope.isFunction()){
let retValue=InterpreterModule.getCurrentScope().getReturnValue();
parentScope.setReturnStatement(true,retValue);
return false;
}
InterpreterModule.getVisitor(statement.type).visitNode(statement);
return true;
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import Visitor from ".";
import { ASTNode } from "bhai-lang-parser";
import RuntimeException from "../../exceptions/runtimeException";
import { BooleanObject } from "../dataClass";

export default class BooleanLiteral implements Visitor {
visitNode(node: ASTNode) {
return node.value;
if(node.value!=="sahi"&&node.value!=="galat")
throw new RuntimeException(`Ye kya kar raha hai: "${node.value}" sahi nhi hai ${node.type} me. isme sahi/galat dal`);
return new BooleanObject(node.value === "sahi" ? true : false);
}
}
Loading